about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast/src/ast.rs10
-rw-r--r--compiler/rustc_ast/src/mut_visit.rs9
-rw-r--r--compiler/rustc_ast/src/token.rs12
-rw-r--r--compiler/rustc_ast/src/util/literal.rs41
-rw-r--r--compiler/rustc_ast/src/visit.rs2
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs9
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs6
-rw-r--r--compiler/rustc_ast_passes/src/ast_validation.rs3
-rw-r--r--compiler/rustc_ast_pretty/src/pprust/state.rs9
-rw-r--r--compiler/rustc_borrowck/src/universal_regions.rs7
-rw-r--r--compiler/rustc_builtin_macros/src/concat.rs2
-rw-r--r--compiler/rustc_builtin_macros/src/concat_bytes.rs2
-rw-r--r--compiler/rustc_codegen_llvm/src/back/lto.rs6
-rw-r--r--compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs1
-rw-r--r--compiler/rustc_codegen_llvm/src/llvm_util.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/assert_module_sources.rs10
-rw-r--r--compiler/rustc_codegen_ssa/src/back/archive.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/back/link.rs26
-rw-r--r--compiler/rustc_codegen_ssa/src/back/write.rs4
-rw-r--r--compiler/rustc_codegen_ssa/src/base.rs15
-rw-r--r--compiler/rustc_codegen_ssa/src/lib.rs14
-rw-r--r--compiler/rustc_const_eval/messages.ftl2
-rw-r--r--compiler/rustc_const_eval/src/const_eval/error.rs4
-rw-r--r--compiler/rustc_const_eval/src/const_eval/eval_queries.rs82
-rw-r--r--compiler/rustc_const_eval/src/const_eval/machine.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/cast.rs4
-rw-r--r--compiler/rustc_const_eval/src/interpret/eval_context.rs14
-rw-r--r--compiler/rustc_const_eval/src/interpret/intern.rs32
-rw-r--r--compiler/rustc_const_eval/src/interpret/intrinsics.rs14
-rw-r--r--compiler/rustc_const_eval/src/interpret/machine.rs15
-rw-r--r--compiler/rustc_const_eval/src/interpret/memory.rs34
-rw-r--r--compiler/rustc_const_eval/src/interpret/mod.rs1
-rw-r--r--compiler/rustc_const_eval/src/interpret/place.rs47
-rw-r--r--compiler/rustc_const_eval/src/interpret/step.rs8
-rw-r--r--compiler/rustc_const_eval/src/interpret/terminator.rs2
-rw-r--r--compiler/rustc_const_eval/src/interpret/util.rs28
-rw-r--r--compiler/rustc_const_eval/src/interpret/validity.rs19
-rw-r--r--compiler/rustc_const_eval/src/lib.rs1
-rw-r--r--compiler/rustc_data_structures/src/unord.rs5
-rw-r--r--compiler/rustc_errors/src/diagnostic.rs9
-rw-r--r--compiler/rustc_errors/src/emitter.rs19
-rw-r--r--compiler/rustc_errors/src/lib.rs3
-rw-r--r--compiler/rustc_expand/src/base.rs11
-rw-r--r--compiler/rustc_expand/src/proc_macro_server.rs22
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/bounds.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/errors.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/astconv/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/explicit.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs10
-rw-r--r--compiler/rustc_hir_typeck/src/expr.rs12
-rw-r--r--compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs2
-rw-r--r--compiler/rustc_interface/src/passes.rs6
-rw-r--r--compiler/rustc_lint/src/context.rs22
-rw-r--r--compiler/rustc_lint/src/non_ascii_idents.rs1
-rw-r--r--compiler/rustc_lint/src/reference_casting.rs7
-rw-r--r--compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs9
-rw-r--r--compiler/rustc_metadata/src/rmeta/encoder.rs14
-rw-r--r--compiler/rustc_metadata/src/rmeta/mod.rs1
-rw-r--r--compiler/rustc_middle/src/mir/interpret/error.rs3
-rw-r--r--compiler/rustc_middle/src/mir/interpret/mod.rs11
-rw-r--r--compiler/rustc_middle/src/mir/interpret/queries.rs51
-rw-r--r--compiler/rustc_middle/src/mir/mod.rs2
-rw-r--r--compiler/rustc_middle/src/mir/mono.rs9
-rw-r--r--compiler/rustc_middle/src/mir/pretty.rs2
-rw-r--r--compiler/rustc_middle/src/query/erase.rs1
-rw-r--r--compiler/rustc_middle/src/query/mod.rs15
-rw-r--r--compiler/rustc_middle/src/ty/parameterized.rs1
-rw-r--r--compiler/rustc_middle/src/ty/sty.rs37
-rw-r--r--compiler/rustc_mir_build/src/build/expr/as_constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/constant.rs6
-rw-r--r--compiler/rustc_mir_build/src/thir/cx/expr.rs12
-rw-r--r--compiler/rustc_mir_transform/src/gvn.rs5
-rw-r--r--compiler/rustc_mir_transform/src/jump_threading.rs6
-rw-r--r--compiler/rustc_monomorphize/src/partitioning.rs4
-rw-r--r--compiler/rustc_parse/src/lexer/mod.rs54
-rw-r--r--compiler/rustc_parse/src/lexer/unescape_error_reporting.rs58
-rw-r--r--compiler/rustc_parse/src/parser/diagnostics.rs20
-rw-r--r--compiler/rustc_parse/src/parser/expr.rs4
-rw-r--r--compiler/rustc_parse/src/parser/item.rs26
-rw-r--r--compiler/rustc_parse/src/parser/mod.rs2
-rw-r--r--compiler/rustc_parse/src/parser/path.rs7
-rw-r--r--compiler/rustc_parse/src/parser/ty.rs10
-rw-r--r--compiler/rustc_parse/src/validate_attr.rs4
-rw-r--r--compiler/rustc_passes/src/hir_stats.rs5
-rw-r--r--compiler/rustc_session/src/errors.rs58
-rw-r--r--compiler/rustc_session/src/parse.rs12
-rw-r--r--compiler/rustc_trait_selection/messages.ftl12
-rw-r--r--compiler/rustc_trait_selection/src/errors.rs10
-rw-r--r--compiler/rustc_trait_selection/src/solve/trait_goals.rs23
-rw-r--r--compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs123
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs95
-rw-r--r--compiler/rustc_trait_selection/src/traits/select/mod.rs13
-rw-r--r--library/alloc/src/collections/btree/map.rs12
-rw-r--r--library/alloc/src/rc.rs74
-rw-r--r--library/alloc/src/sync.rs74
-rw-r--r--library/core/src/str/validations.rs2
-rw-r--r--library/core/src/task/wake.rs4
-rw-r--r--library/core/src/unicode/unicode_data.rs12
-rw-r--r--library/proc_macro/src/bridge/mod.rs8
-rw-r--r--library/proc_macro/src/lib.rs2
-rw-r--r--library/std/src/sys/pal/unix/thread.rs30
-rw-r--r--src/librustdoc/doctest.rs18
-rw-r--r--src/librustdoc/doctest/tests.rs44
-rw-r--r--src/librustdoc/html/markdown.rs7
-rw-r--r--src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs3
-rw-r--r--src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs2
-rw-r--r--src/tools/clippy/clippy_lints/src/utils/author.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/ast_utils.rs2
-rw-r--r--src/tools/clippy/clippy_utils/src/consts.rs2
-rw-r--r--src/tools/clippy/tests/ui/match_str_case_mismatch.stderr2
-rw-r--r--src/tools/miri/src/shims/intrinsics/mod.rs4
-rw-r--r--src/tools/miri/src/shims/x86/mod.rs3
-rw-r--r--src/tools/miri/src/shims/x86/sse.rs1
-rw-r--r--src/tools/miri/src/shims/x86/sse2.rs2
-rw-r--r--src/tools/miri/src/shims/x86/sse41.rs1
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server/rust_analyzer_span.rs4
-rw-r--r--src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_id.rs4
-rw-r--r--src/tools/rustfmt/src/types.rs2
-rw-r--r--tests/rustdoc/playground-arg.rs2
-rw-r--r--tests/rustdoc/playground.rs2
-rw-r--r--tests/ui/asm/x86_64/evex512-implicit-feature.rs15
-rw-r--r--tests/ui/async-await/async-closures/not-fn.rs15
-rw-r--r--tests/ui/async-await/async-closures/not-fn.stderr16
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.rs3
-rw-r--r--tests/ui/async-await/async-closures/wrong-fn-kind.stderr12
-rw-r--r--tests/ui/const-generics/wrong-normalization.rs1
-rw-r--r--tests/ui/const-generics/wrong-normalization.stderr16
-rw-r--r--tests/ui/consts/recursive-zst-static.default.stderr26
-rw-r--r--tests/ui/consts/recursive-zst-static.rs6
-rw-r--r--tests/ui/consts/recursive-zst-static.unleash.stderr26
-rw-r--r--tests/ui/consts/write-to-static-mut-in-static.rs2
-rw-r--r--tests/ui/consts/write-to-static-mut-in-static.stderr25
-rw-r--r--tests/ui/error-codes/E0423.stderr2
-rw-r--r--tests/ui/impl-trait/where-allowed.rs6
-rw-r--r--tests/ui/impl-trait/where-allowed.stderr145
-rw-r--r--tests/ui/issues/issue-4265.rs1
-rw-r--r--tests/ui/issues/issue-4265.stderr26
-rw-r--r--tests/ui/kinds-of-primitive-impl.rs2
-rw-r--r--tests/ui/kinds-of-primitive-impl.stderr18
-rw-r--r--tests/ui/lint/reference_casting.rs5
-rw-r--r--tests/ui/mir/mir_query_cycle.rs14
-rw-r--r--tests/ui/parser/emoji-identifiers.stderr16
-rw-r--r--tests/ui/parser/impl-item-type-no-body-semantic-fail.rs2
-rw-r--r--tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr40
-rw-r--r--tests/ui/parser/kw-in-trait-bounds.stderr8
-rw-r--r--tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr4
-rw-r--r--tests/ui/parser/typod-const-in-const-param-def.stderr8
-rw-r--r--tests/ui/recursion/recursive-static-definition.rs10
-rw-r--r--tests/ui/recursion/recursive-static-definition.stderr23
-rw-r--r--tests/ui/statics/recursive_interior_mut.rs20
-rw-r--r--tests/ui/suggestions/assoc-ct-for-assoc-method.stderr2
-rw-r--r--tests/ui/suggestions/bool_typo_err_suggest.stderr2
-rw-r--r--tests/ui/traits/issue-33140.rs2
-rw-r--r--tests/ui/traits/issue-33140.stderr40
-rw-r--r--tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs14
-rw-r--r--tests/ui/treat-err-as-bug/err.rs2
-rw-r--r--tests/ui/treat-err-as-bug/err.stderr2
163 files changed, 1585 insertions, 758 deletions
diff --git a/compiler/rustc_ast/src/ast.rs b/compiler/rustc_ast/src/ast.rs
index 098e2606a3b..3fdb2a2225a 100644
--- a/compiler/rustc_ast/src/ast.rs
+++ b/compiler/rustc_ast/src/ast.rs
@@ -1846,7 +1846,7 @@ pub enum LitKind {
     /// A boolean literal (`true`, `false`).
     Bool(bool),
     /// Placeholder for a literal that wasn't well-formed in some way.
-    Err,
+    Err(ErrorGuaranteed),
 }
 
 impl LitKind {
@@ -1893,7 +1893,7 @@ impl LitKind {
             | LitKind::Int(_, LitIntType::Unsuffixed)
             | LitKind::Float(_, LitFloatType::Unsuffixed)
             | LitKind::Bool(..)
-            | LitKind::Err => false,
+            | LitKind::Err(_) => false,
         }
     }
 }
@@ -2136,10 +2136,12 @@ pub enum TyKind {
     ImplicitSelf,
     /// A macro in the type position.
     MacCall(P<MacCall>),
-    /// Placeholder for a kind that has failed to be defined.
-    Err,
     /// Placeholder for a `va_list`.
     CVarArgs,
+    /// Sometimes we need a dummy value when no error has occurred.
+    Dummy,
+    /// Placeholder for a kind that has failed to be defined.
+    Err(ErrorGuaranteed),
 }
 
 impl TyKind {
diff --git a/compiler/rustc_ast/src/mut_visit.rs b/compiler/rustc_ast/src/mut_visit.rs
index d482ada170e..c42c4199973 100644
--- a/compiler/rustc_ast/src/mut_visit.rs
+++ b/compiler/rustc_ast/src/mut_visit.rs
@@ -481,7 +481,12 @@ pub fn noop_visit_ty<T: MutVisitor>(ty: &mut P<Ty>, vis: &mut T) {
     let Ty { id, kind, span, tokens } = ty.deref_mut();
     vis.visit_id(id);
     match kind {
-        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err | TyKind::Never | TyKind::CVarArgs => {}
+        TyKind::Infer
+        | TyKind::ImplicitSelf
+        | TyKind::Err(_)
+        | TyKind::Dummy
+        | TyKind::Never
+        | TyKind::CVarArgs => {}
         TyKind::Slice(ty) => vis.visit_ty(ty),
         TyKind::Ptr(mt) => vis.visit_mt(mt),
         TyKind::Ref(lt, mt) => {
@@ -1649,7 +1654,7 @@ impl DummyAstNode for Ty {
     fn dummy() -> Self {
         Ty {
             id: DUMMY_NODE_ID,
-            kind: TyKind::Err,
+            kind: TyKind::Dummy,
             span: Default::default(),
             tokens: Default::default(),
         }
diff --git a/compiler/rustc_ast/src/token.rs b/compiler/rustc_ast/src/token.rs
index d62462b1ae3..50fe37dcdb6 100644
--- a/compiler/rustc_ast/src/token.rs
+++ b/compiler/rustc_ast/src/token.rs
@@ -13,7 +13,7 @@ use rustc_macros::HashStable_Generic;
 use rustc_span::symbol::{kw, sym};
 #[allow(hidden_glob_reexports)]
 use rustc_span::symbol::{Ident, Symbol};
-use rustc_span::{edition::Edition, Span, DUMMY_SP};
+use rustc_span::{edition::Edition, ErrorGuaranteed, Span, DUMMY_SP};
 use std::borrow::Cow;
 use std::fmt;
 
@@ -75,7 +75,7 @@ pub enum LitKind {
     ByteStrRaw(u8), // raw byte string delimited by `n` hash symbols
     CStr,
     CStrRaw(u8),
-    Err,
+    Err(ErrorGuaranteed),
 }
 
 /// A literal token.
@@ -144,7 +144,7 @@ impl fmt::Display for Lit {
             CStrRaw(n) => {
                 write!(f, "cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))?
             }
-            Integer | Float | Bool | Err => write!(f, "{symbol}")?,
+            Integer | Float | Bool | Err(_) => write!(f, "{symbol}")?,
         }
 
         if let Some(suffix) = suffix {
@@ -159,7 +159,7 @@ impl LitKind {
     /// An English article for the literal token kind.
     pub fn article(self) -> &'static str {
         match self {
-            Integer | Err => "an",
+            Integer | Err(_) => "an",
             _ => "a",
         }
     }
@@ -174,12 +174,12 @@ impl LitKind {
             Str | StrRaw(..) => "string",
             ByteStr | ByteStrRaw(..) => "byte string",
             CStr | CStrRaw(..) => "C string",
-            Err => "error",
+            Err(_) => "error",
         }
     }
 
     pub(crate) fn may_have_suffix(self) -> bool {
-        matches!(self, Integer | Float | Err)
+        matches!(self, Integer | Float | Err(_))
     }
 }
 
diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs
index aaeb1bb9bff..5ed2762b726 100644
--- a/compiler/rustc_ast/src/util/literal.rs
+++ b/compiler/rustc_ast/src/util/literal.rs
@@ -31,20 +31,21 @@ pub fn escape_byte_str_symbol(bytes: &[u8]) -> Symbol {
 
 #[derive(Debug)]
 pub enum LitError {
-    LexerError,
-    InvalidSuffix,
-    InvalidIntSuffix,
-    InvalidFloatSuffix,
-    NonDecimalFloat(u32),
-    IntTooLarge(u32),
+    InvalidSuffix(Symbol),
+    InvalidIntSuffix(Symbol),
+    InvalidFloatSuffix(Symbol),
+    NonDecimalFloat(u32), // u32 is the base
+    IntTooLarge(u32),     // u32 is the base
 }
 
 impl LitKind {
     /// Converts literal token into a semantic literal.
     pub fn from_token_lit(lit: token::Lit) -> Result<LitKind, LitError> {
         let token::Lit { kind, symbol, suffix } = lit;
-        if suffix.is_some() && !kind.may_have_suffix() {
-            return Err(LitError::InvalidSuffix);
+        if let Some(suffix) = suffix
+            && !kind.may_have_suffix()
+        {
+            return Err(LitError::InvalidSuffix(suffix));
         }
 
         // For byte/char/string literals, chars and escapes have already been
@@ -145,7 +146,7 @@ impl LitKind {
                 buf.push(0);
                 LitKind::CStr(buf.into(), StrStyle::Raw(n))
             }
-            token::Err => LitKind::Err,
+            token::Err(guar) => LitKind::Err(guar),
         })
     }
 }
@@ -202,7 +203,7 @@ impl fmt::Display for LitKind {
                 }
             }
             LitKind::Bool(b) => write!(f, "{}", if b { "true" } else { "false" })?,
-            LitKind::Err => {
+            LitKind::Err(_) => {
                 // This only shows up in places like `-Zunpretty=hir` output, so we
                 // don't bother to produce something useful.
                 write!(f, "<bad-literal>")?;
@@ -238,7 +239,7 @@ impl MetaItemLit {
             LitKind::Char(_) => token::Char,
             LitKind::Int(..) => token::Integer,
             LitKind::Float(..) => token::Float,
-            LitKind::Err => token::Err,
+            LitKind::Err(guar) => token::Err(guar),
         };
 
         token::Lit::new(kind, self.symbol, self.suffix)
@@ -272,12 +273,12 @@ fn filtered_float_lit(
         return Err(LitError::NonDecimalFloat(base));
     }
     Ok(match suffix {
-        Some(suf) => LitKind::Float(
+        Some(suffix) => LitKind::Float(
             symbol,
-            ast::LitFloatType::Suffixed(match suf {
+            ast::LitFloatType::Suffixed(match suffix {
                 sym::f32 => ast::FloatTy::F32,
                 sym::f64 => ast::FloatTy::F64,
-                _ => return Err(LitError::InvalidFloatSuffix),
+                _ => return Err(LitError::InvalidFloatSuffix(suffix)),
             }),
         ),
         None => LitKind::Float(symbol, ast::LitFloatType::Unsuffixed),
@@ -318,17 +319,13 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
             // `1f64` and `2f32` etc. are valid float literals, and
             // `fxxx` looks more like an invalid float literal than invalid integer literal.
             _ if suf.as_str().starts_with('f') => return filtered_float_lit(symbol, suffix, base),
-            _ => return Err(LitError::InvalidIntSuffix),
+            _ => return Err(LitError::InvalidIntSuffix(suf)),
         },
         _ => ast::LitIntType::Unsuffixed,
     };
 
     let s = &s[if base != 10 { 2 } else { 0 }..];
-    u128::from_str_radix(s, base).map(|i| LitKind::Int(i.into(), ty)).map_err(|_| {
-        // Small bases are lexed as if they were base 10, e.g, the string
-        // might be `0b10201`. This will cause the conversion above to fail,
-        // but these kinds of errors are already reported by the lexer.
-        let from_lexer = base < 10 && s.chars().any(|c| c.to_digit(10).is_some_and(|d| d >= base));
-        if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) }
-    })
+    u128::from_str_radix(s, base)
+        .map(|i| LitKind::Int(i.into(), ty))
+        .map_err(|_| LitError::IntTooLarge(base))
 }
diff --git a/compiler/rustc_ast/src/visit.rs b/compiler/rustc_ast/src/visit.rs
index 4aaaa0ba424..83f6746bdeb 100644
--- a/compiler/rustc_ast/src/visit.rs
+++ b/compiler/rustc_ast/src/visit.rs
@@ -447,7 +447,7 @@ pub fn walk_ty<'a, V: Visitor<'a>>(visitor: &mut V, typ: &'a Ty) {
             walk_list!(visitor, visit_param_bound, bounds, BoundKind::Impl);
         }
         TyKind::Typeof(expression) => visitor.visit_anon_const(expression),
-        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Err => {}
+        TyKind::Infer | TyKind::ImplicitSelf | TyKind::Dummy | TyKind::Err(_) => {}
         TyKind::MacCall(mac) => visitor.visit_mac_call(mac),
         TyKind::Never | TyKind::CVarArgs => {}
         TyKind::AnonStruct(_, ref fields) | TyKind::AnonUnion(_, ref fields) => {
diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs
index 942aae3d536..aafa99b3aa6 100644
--- a/compiler/rustc_ast_lowering/src/expr.rs
+++ b/compiler/rustc_ast_lowering/src/expr.rs
@@ -124,8 +124,13 @@ impl<'hir> LoweringContext<'_, 'hir> {
                     let lit_kind = match LitKind::from_token_lit(*token_lit) {
                         Ok(lit_kind) => lit_kind,
                         Err(err) => {
-                            report_lit_error(&self.tcx.sess.parse_sess, err, *token_lit, e.span);
-                            LitKind::Err
+                            let guar = report_lit_error(
+                                &self.tcx.sess.parse_sess,
+                                err,
+                                *token_lit,
+                                e.span,
+                            );
+                            LitKind::Err(guar)
                         }
                     };
                     let lit = self.arena.alloc(respan(self.lower_span(e.span), lit_kind));
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 6b5fc014240..e9e1095a4ae 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -966,10 +966,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 {
                     lit
                 } else {
+                    let guar = self.dcx().has_errors().unwrap();
                     MetaItemLit {
                         symbol: kw::Empty,
                         suffix: None,
-                        kind: LitKind::Err,
+                        kind: LitKind::Err(guar),
                         span: DUMMY_SP,
                     }
                 };
@@ -1285,7 +1286,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
     fn lower_ty_direct(&mut self, t: &Ty, itctx: ImplTraitContext) -> hir::Ty<'hir> {
         let kind = match &t.kind {
             TyKind::Infer => hir::TyKind::Infer,
-            TyKind::Err => hir::TyKind::Err(self.dcx().has_errors().unwrap()),
+            TyKind::Err(guar) => hir::TyKind::Err(*guar),
             // Lower the anonymous structs or unions in a nested lowering context.
             //
             // ```
@@ -1503,6 +1504,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
                 );
                 hir::TyKind::Err(guar)
             }
+            TyKind::Dummy => panic!("`TyKind::Dummy` should never be lowered"),
         };
 
         hir::Ty { kind, span: self.lower_span(t.span), hir_id: self.lower_node_id(t.id) }
diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs
index ebc5c17a4c4..fa0f5326196 100644
--- a/compiler/rustc_ast_passes/src/ast_validation.rs
+++ b/compiler/rustc_ast_passes/src/ast_validation.rs
@@ -881,7 +881,8 @@ impl<'a> Visitor<'a> for AstValidator<'a> {
                         &item.vis,
                         errors::VisibilityNotPermittedNote::TraitImpl,
                     );
-                    if let TyKind::Err = self_ty.kind {
+                    // njn: use Dummy here
+                    if let TyKind::Err(_) = self_ty.kind {
                         this.dcx().emit_err(errors::ObsoleteAuto { span: item.span });
                     }
                     if let (&Unsafe::Yes(span), &ImplPolarity::Negative(sp)) = (unsafety, polarity)
diff --git a/compiler/rustc_ast_pretty/src/pprust/state.rs b/compiler/rustc_ast_pretty/src/pprust/state.rs
index cda746894e8..7ea0078ea3b 100644
--- a/compiler/rustc_ast_pretty/src/pprust/state.rs
+++ b/compiler/rustc_ast_pretty/src/pprust/state.rs
@@ -254,7 +254,7 @@ fn literal_to_string(lit: token::Lit) -> String {
         token::CStrRaw(n) => {
             format!("cr{delim}\"{symbol}\"{delim}", delim = "#".repeat(n as usize))
         }
-        token::Integer | token::Float | token::Bool | token::Err => symbol.to_string(),
+        token::Integer | token::Float | token::Bool | token::Err(_) => symbol.to_string(),
     };
 
     if let Some(suffix) = suffix {
@@ -1048,11 +1048,16 @@ impl<'a> State<'a> {
             ast::TyKind::Infer => {
                 self.word("_");
             }
-            ast::TyKind::Err => {
+            ast::TyKind::Err(_) => {
                 self.popen();
                 self.word("/*ERROR*/");
                 self.pclose();
             }
+            ast::TyKind::Dummy => {
+                self.popen();
+                self.word("/*DUMMY*/");
+                self.pclose();
+            }
             ast::TyKind::ImplicitSelf => {
                 self.word("Self");
             }
diff --git a/compiler/rustc_borrowck/src/universal_regions.rs b/compiler/rustc_borrowck/src/universal_regions.rs
index a7bdfa4eae7..90e8f1b93b2 100644
--- a/compiler/rustc_borrowck/src/universal_regions.rs
+++ b/compiler/rustc_borrowck/src/universal_regions.rs
@@ -15,7 +15,7 @@
 #![allow(rustc::diagnostic_outside_of_impl)]
 #![allow(rustc::untranslatable_diagnostic)]
 
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::Diagnostic;
 use rustc_hir::def_id::{DefId, LocalDefId};
 use rustc_hir::lang_items::LangItem;
@@ -180,7 +180,7 @@ struct UniversalRegionIndices<'tcx> {
     /// basically equivalent to an `GenericArgs`, except that it also
     /// contains an entry for `ReStatic` -- it might be nice to just
     /// use an args, and then handle `ReStatic` another way.
-    indices: FxHashMap<ty::Region<'tcx>, RegionVid>,
+    indices: FxIndexMap<ty::Region<'tcx>, RegionVid>,
 
     /// The vid assigned to `'static`. Used only for diagnostics.
     pub fr_static: RegionVid,
@@ -325,9 +325,6 @@ impl<'tcx> UniversalRegions<'tcx> {
     }
 
     /// Gets an iterator over all the early-bound regions that have names.
-    /// Iteration order may be unstable, so this should only be used when
-    /// iteration order doesn't affect anything
-    #[allow(rustc::potential_query_instability)]
     pub fn named_universal_regions<'s>(
         &'s self,
     ) -> impl Iterator<Item = (ty::Region<'tcx>, ty::RegionVid)> + 's {
diff --git a/compiler/rustc_builtin_macros/src/concat.rs b/compiler/rustc_builtin_macros/src/concat.rs
index dade29593af..795161e65d8 100644
--- a/compiler/rustc_builtin_macros/src/concat.rs
+++ b/compiler/rustc_builtin_macros/src/concat.rs
@@ -40,7 +40,7 @@ pub fn expand_concat(
                     cx.dcx().emit_err(errors::ConcatBytestr { span: e.span });
                     has_errors = true;
                 }
-                Ok(ast::LitKind::Err) => {
+                Ok(ast::LitKind::Err(_)) => {
                     has_errors = true;
                 }
                 Err(err) => {
diff --git a/compiler/rustc_builtin_macros/src/concat_bytes.rs b/compiler/rustc_builtin_macros/src/concat_bytes.rs
index a01bbeac824..3ef8cb7bffe 100644
--- a/compiler/rustc_builtin_macros/src/concat_bytes.rs
+++ b/compiler/rustc_builtin_macros/src/concat_bytes.rs
@@ -44,7 +44,7 @@ fn invalid_type_err(
         Ok(ast::LitKind::Bool(_)) => {
             dcx.emit_err(ConcatBytesInvalid { span, lit_kind: "boolean", sugg: None });
         }
-        Ok(ast::LitKind::Err) => {}
+        Ok(ast::LitKind::Err(_)) => {}
         Ok(ast::LitKind::Int(_, _)) if !is_nested => {
             let sugg =
                 snippet.map(|snippet| ConcatBytesInvalidSuggestion::IntLit { span: span, snippet });
diff --git a/compiler/rustc_codegen_llvm/src/back/lto.rs b/compiler/rustc_codegen_llvm/src/back/lto.rs
index 42bd8687042..06a681c24e6 100644
--- a/compiler/rustc_codegen_llvm/src/back/lto.rs
+++ b/compiler/rustc_codegen_llvm/src/back/lto.rs
@@ -21,6 +21,7 @@ use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::exported_symbols::{SymbolExportInfo, SymbolExportLevel};
 use rustc_session::config::{self, CrateType, Lto};
 
+use std::collections::BTreeMap;
 use std::ffi::{CStr, CString};
 use std::fs::File;
 use std::io;
@@ -787,7 +788,7 @@ pub unsafe fn optimize_thin_module(
 #[derive(Debug, Default)]
 pub struct ThinLTOKeysMap {
     // key = llvm name of importing module, value = LLVM cache key
-    keys: FxHashMap<String, String>,
+    keys: BTreeMap<String, String>,
 }
 
 impl ThinLTOKeysMap {
@@ -797,7 +798,6 @@ impl ThinLTOKeysMap {
         let mut writer = io::BufWriter::new(file);
         // The entries are loaded back into a hash map in `load_from_file()`, so
         // the order in which we write them to file here does not matter.
-        #[allow(rustc::potential_query_instability)]
         for (module, key) in &self.keys {
             writeln!(writer, "{module} {key}")?;
         }
@@ -806,7 +806,7 @@ impl ThinLTOKeysMap {
 
     fn load_from_file(path: &Path) -> io::Result<Self> {
         use std::io::BufRead;
-        let mut keys = FxHashMap::default();
+        let mut keys = BTreeMap::default();
         let file = File::open(path)?;
         for line in io::BufReader::new(file).lines() {
             let line = line?;
diff --git a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
index b1ceb1d4dd5..6116a6fd222 100644
--- a/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
+++ b/compiler/rustc_codegen_llvm/src/coverageinfo/mapgen.rs
@@ -403,7 +403,6 @@ fn codegenned_and_inlined_items(tcx: TyCtxt<'_>) -> DefIdSet {
     let mut result = items.clone();
 
     for cgu in cgus {
-        #[allow(rustc::potential_query_instability)]
         for item in cgu.items().keys() {
             if let mir::mono::MonoItem::Fn(ref instance) = item {
                 let did = instance.def_id();
diff --git a/compiler/rustc_codegen_llvm/src/llvm_util.rs b/compiler/rustc_codegen_llvm/src/llvm_util.rs
index e48479c8da2..54e8ed85e32 100644
--- a/compiler/rustc_codegen_llvm/src/llvm_util.rs
+++ b/compiler/rustc_codegen_llvm/src/llvm_util.rs
@@ -266,6 +266,10 @@ pub fn to_llvm_features<'a>(sess: &Session, s: &'a str) -> LLVMFeature<'a> {
         ("riscv32" | "riscv64", "fast-unaligned-access") if get_version().0 <= 17 => {
             LLVMFeature::new("unaligned-scalar-mem")
         }
+        // For LLVM 18, enable the evex512 target feature if a avx512 target feature is enabled.
+        ("x86", s) if get_version().0 >= 18 && s.starts_with("avx512") => {
+            LLVMFeature::with_dependency(s, TargetFeatureFoldStrength::EnableOnly("evex512"))
+        }
         (_, s) => LLVMFeature::new(s),
     }
 }
diff --git a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
index 3e5a43c6e73..344e7dbdf03 100644
--- a/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
+++ b/compiler/rustc_codegen_ssa/src/assert_module_sources.rs
@@ -25,7 +25,7 @@
 
 use crate::errors;
 use rustc_ast as ast;
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::unord::UnordMap;
 use rustc_data_structures::unord::UnordSet;
 use rustc_errors::{DiagnosticArgValue, IntoDiagnosticArg};
 use rustc_hir::def_id::LOCAL_CRATE;
@@ -218,8 +218,8 @@ pub enum ComparisonKind {
 }
 
 struct TrackerData {
-    actual_reuse: FxHashMap<String, CguReuse>,
-    expected_reuse: FxHashMap<String, (String, Span, CguReuse, ComparisonKind)>,
+    actual_reuse: UnordMap<String, CguReuse>,
+    expected_reuse: UnordMap<String, (String, Span, CguReuse, ComparisonKind)>,
 }
 
 pub struct CguReuseTracker {
@@ -267,9 +267,7 @@ impl CguReuseTracker {
 
     fn check_expected_reuse(&self, sess: &Session) {
         if let Some(ref data) = self.data {
-            #[allow(rustc::potential_query_instability)]
-            let mut keys = data.expected_reuse.keys().collect::<Vec<_>>();
-            keys.sort_unstable();
+            let keys = data.expected_reuse.keys().into_sorted_stable_ord();
             for cgu_name in keys {
                 let &(ref cgu_user_name, ref error_span, expected_reuse, comparison_kind) =
                     data.expected_reuse.get(cgu_name).unwrap();
diff --git a/compiler/rustc_codegen_ssa/src/back/archive.rs b/compiler/rustc_codegen_ssa/src/back/archive.rs
index 8d7ad24b446..0dadd047c9a 100644
--- a/compiler/rustc_codegen_ssa/src/back/archive.rs
+++ b/compiler/rustc_codegen_ssa/src/back/archive.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_data_structures::memmap::Mmap;
 use rustc_session::cstore::DllImport;
 use rustc_session::Session;
@@ -41,7 +41,7 @@ pub trait ArchiveBuilderBuilder {
         &'a self,
         rlib: &'a Path,
         outdir: &Path,
-        bundled_lib_file_names: &FxHashSet<Symbol>,
+        bundled_lib_file_names: &FxIndexSet<Symbol>,
     ) -> Result<(), ExtractBundledLibsError<'_>> {
         let archive_map = unsafe {
             Mmap::map(
diff --git a/compiler/rustc_codegen_ssa/src/back/link.rs b/compiler/rustc_codegen_ssa/src/back/link.rs
index b29f71bfb95..435b517e602 100644
--- a/compiler/rustc_codegen_ssa/src/back/link.rs
+++ b/compiler/rustc_codegen_ssa/src/back/link.rs
@@ -1,7 +1,6 @@
 use rustc_arena::TypedArena;
 use rustc_ast::CRATE_NODE_ID;
-use rustc_data_structures::fx::FxHashSet;
-use rustc_data_structures::fx::FxIndexMap;
+use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::memmap::Mmap;
 use rustc_data_structures::temp_dir::MaybeTempDir;
 use rustc_errors::{DiagCtxt, ErrorGuaranteed};
@@ -534,9 +533,9 @@ fn link_staticlib<'a>(
 
             let native_libs = codegen_results.crate_info.native_libraries[&cnum].iter();
             let relevant = native_libs.clone().filter(|lib| relevant_lib(sess, lib));
-            let relevant_libs: FxHashSet<_> = relevant.filter_map(|lib| lib.filename).collect();
+            let relevant_libs: FxIndexSet<_> = relevant.filter_map(|lib| lib.filename).collect();
 
-            let bundled_libs: FxHashSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
+            let bundled_libs: FxIndexSet<_> = native_libs.filter_map(|lib| lib.filename).collect();
             ab.add_archive(
                 path,
                 Box::new(move |fname: &str| {
@@ -564,11 +563,7 @@ fn link_staticlib<'a>(
                 .extract_bundled_libs(path, tempdir.as_ref(), &relevant_libs)
                 .unwrap_or_else(|e| sess.dcx().emit_fatal(e));
 
-            // We sort the libraries below
-            #[allow(rustc::potential_query_instability)]
-            let mut relevant_libs: Vec<Symbol> = relevant_libs.into_iter().collect();
-            relevant_libs.sort_unstable();
-            for filename in relevant_libs {
+            for filename in relevant_libs.iter() {
                 let joined = tempdir.as_ref().join(filename.as_str());
                 let path = joined.as_path();
                 ab.add_archive(path, Box::new(|_| false)).unwrap();
@@ -682,13 +677,14 @@ fn link_dwarf_object<'a>(
         }
 
         // Input rlibs contain .o/.dwo files from dependencies.
-        #[allow(rustc::potential_query_instability)]
         let input_rlibs = cg_results
             .crate_info
             .used_crate_source
-            .values()
-            .filter_map(|csource| csource.rlib.as_ref())
-            .map(|(path, _)| path);
+            .items()
+            .filter_map(|(_, csource)| csource.rlib.as_ref())
+            .map(|(path, _)| path)
+            .into_sorted_stable_ord();
+
         for input_rlib in input_rlibs {
             debug!(?input_rlib);
             package.add_input_object(input_rlib)?;
@@ -2456,7 +2452,7 @@ fn add_native_libs_from_crate(
     codegen_results: &CodegenResults,
     tmpdir: &Path,
     search_paths: &SearchPaths,
-    bundled_libs: &FxHashSet<Symbol>,
+    bundled_libs: &FxIndexSet<Symbol>,
     cnum: CrateNum,
     link_static: bool,
     link_dynamic: bool,
@@ -2777,7 +2773,7 @@ fn add_static_crate<'a>(
     codegen_results: &CodegenResults,
     tmpdir: &Path,
     cnum: CrateNum,
-    bundled_lib_file_names: &FxHashSet<Symbol>,
+    bundled_lib_file_names: &FxIndexSet<Symbol>,
 ) {
     let src = &codegen_results.crate_info.used_crate_source[&cnum];
     let cratepath = &src.rlib.as_ref().unwrap().0;
diff --git a/compiler/rustc_codegen_ssa/src/back/write.rs b/compiler/rustc_codegen_ssa/src/back/write.rs
index a63642d76b9..24fdd013509 100644
--- a/compiler/rustc_codegen_ssa/src/back/write.rs
+++ b/compiler/rustc_codegen_ssa/src/back/write.rs
@@ -1001,7 +1001,7 @@ pub struct CguMessage;
 
 struct Diagnostic {
     msgs: Vec<(DiagnosticMessage, Style)>,
-    args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
+    args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue>,
     code: Option<ErrCode>,
     lvl: Level,
 }
@@ -1813,7 +1813,7 @@ impl Translate for SharedEmitter {
 
 impl Emitter for SharedEmitter {
     fn emit_diagnostic(&mut self, diag: rustc_errors::Diagnostic) {
-        let args: FxHashMap<DiagnosticArgName, DiagnosticArgValue> =
+        let args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue> =
             diag.args().map(|(name, arg)| (name.clone(), arg.clone())).collect();
         drop(self.sender.send(SharedEmitterMessage::Diagnostic(Diagnostic {
             msgs: diag.messages.clone(),
diff --git a/compiler/rustc_codegen_ssa/src/base.rs b/compiler/rustc_codegen_ssa/src/base.rs
index 098ea1b793c..760b3f30ee5 100644
--- a/compiler/rustc_codegen_ssa/src/base.rs
+++ b/compiler/rustc_codegen_ssa/src/base.rs
@@ -16,9 +16,10 @@ use crate::{CachedModuleCodegen, CompiledModule, CrateInfo, MemFlags, ModuleCode
 
 use rustc_ast::expand::allocator::{global_fn_name, AllocatorKind, ALLOCATOR_METHODS};
 use rustc_attr as attr;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexSet};
 use rustc_data_structures::profiling::{get_resident_set_size, print_time_passes_entry};
 use rustc_data_structures::sync::par_map;
+use rustc_data_structures::unord::UnordMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::{DefId, LOCAL_CRATE};
 use rustc_hir::lang_items::LangItem;
@@ -851,6 +852,8 @@ impl CrateInfo {
         // `compiler_builtins` are always placed last to ensure that they're linked correctly.
         used_crates.extend(compiler_builtins);
 
+        let crates = tcx.crates(());
+        let n_crates = crates.len();
         let mut info = CrateInfo {
             target_cpu,
             crate_types,
@@ -862,19 +865,15 @@ impl CrateInfo {
             is_no_builtins: Default::default(),
             native_libraries: Default::default(),
             used_libraries: tcx.native_libraries(LOCAL_CRATE).iter().map(Into::into).collect(),
-            crate_name: Default::default(),
+            crate_name: UnordMap::with_capacity(n_crates),
             used_crates,
-            used_crate_source: Default::default(),
+            used_crate_source: UnordMap::with_capacity(n_crates),
             dependency_formats: tcx.dependency_formats(()).clone(),
             windows_subsystem,
             natvis_debugger_visualizers: Default::default(),
         };
-        let crates = tcx.crates(());
 
-        let n_crates = crates.len();
         info.native_libraries.reserve(n_crates);
-        info.crate_name.reserve(n_crates);
-        info.used_crate_source.reserve(n_crates);
 
         for &cnum in crates.iter() {
             info.native_libraries
@@ -901,7 +900,7 @@ impl CrateInfo {
         // by the compiler, but that's ok because all this stuff is unstable anyway.
         let target = &tcx.sess.target;
         if !are_upstream_rust_objects_already_included(tcx.sess) {
-            let missing_weak_lang_items: FxHashSet<Symbol> = info
+            let missing_weak_lang_items: FxIndexSet<Symbol> = info
                 .used_crates
                 .iter()
                 .flat_map(|&cnum| tcx.missing_lang_items(cnum))
diff --git a/compiler/rustc_codegen_ssa/src/lib.rs b/compiler/rustc_codegen_ssa/src/lib.rs
index 1afc597a7ef..92f0be541c0 100644
--- a/compiler/rustc_codegen_ssa/src/lib.rs
+++ b/compiler/rustc_codegen_ssa/src/lib.rs
@@ -24,8 +24,10 @@ extern crate tracing;
 extern crate rustc_middle;
 
 use rustc_ast as ast;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync::Lrc;
+use rustc_data_structures::unord::UnordMap;
 use rustc_hir::def_id::CrateNum;
 use rustc_middle::dep_graph::WorkProduct;
 use rustc_middle::middle::debugger_visualizer::DebuggerVisualizerFile;
@@ -152,16 +154,16 @@ impl From<&cstore::NativeLib> for NativeLib {
 pub struct CrateInfo {
     pub target_cpu: String,
     pub crate_types: Vec<CrateType>,
-    pub exported_symbols: FxHashMap<CrateType, Vec<String>>,
-    pub linked_symbols: FxHashMap<CrateType, Vec<(String, SymbolExportKind)>>,
+    pub exported_symbols: UnordMap<CrateType, Vec<String>>,
+    pub linked_symbols: FxIndexMap<CrateType, Vec<(String, SymbolExportKind)>>,
     pub local_crate_name: Symbol,
     pub compiler_builtins: Option<CrateNum>,
     pub profiler_runtime: Option<CrateNum>,
     pub is_no_builtins: FxHashSet<CrateNum>,
-    pub native_libraries: FxHashMap<CrateNum, Vec<NativeLib>>,
-    pub crate_name: FxHashMap<CrateNum, Symbol>,
+    pub native_libraries: FxIndexMap<CrateNum, Vec<NativeLib>>,
+    pub crate_name: UnordMap<CrateNum, Symbol>,
     pub used_libraries: Vec<NativeLib>,
-    pub used_crate_source: FxHashMap<CrateNum, Lrc<CrateSource>>,
+    pub used_crate_source: UnordMap<CrateNum, Lrc<CrateSource>>,
     pub used_crates: Vec<CrateNum>,
     pub dependency_formats: Lrc<Dependencies>,
     pub windows_subsystem: Option<String>,
diff --git a/compiler/rustc_const_eval/messages.ftl b/compiler/rustc_const_eval/messages.ftl
index 85ebbb00c5f..4a6d4fe930c 100644
--- a/compiler/rustc_const_eval/messages.ftl
+++ b/compiler/rustc_const_eval/messages.ftl
@@ -313,6 +313,8 @@ const_eval_realloc_or_alloc_with_offset =
         *[other] {""}
     } {$ptr} which does not point to the beginning of an object
 
+const_eval_recursive_static = encountered static that tried to initialize itself with itself
+
 const_eval_remainder_by_zero =
     calculating the remainder with a divisor of zero
 const_eval_remainder_overflow =
diff --git a/compiler/rustc_const_eval/src/const_eval/error.rs b/compiler/rustc_const_eval/src/const_eval/error.rs
index 80d02589900..935329f1189 100644
--- a/compiler/rustc_const_eval/src/const_eval/error.rs
+++ b/compiler/rustc_const_eval/src/const_eval/error.rs
@@ -19,6 +19,7 @@ use crate::interpret::{ErrorHandled, InterpError, InterpErrorInfo, MachineStopTy
 pub enum ConstEvalErrKind {
     ConstAccessesMutGlobal,
     ModifiedGlobal,
+    RecursiveStatic,
     AssertFailure(AssertKind<ConstInt>),
     Panic { msg: Symbol, line: u32, col: u32, file: Symbol },
 }
@@ -31,13 +32,14 @@ impl MachineStopType for ConstEvalErrKind {
             ConstAccessesMutGlobal => const_eval_const_accesses_mut_global,
             ModifiedGlobal => const_eval_modified_global,
             Panic { .. } => const_eval_panic,
+            RecursiveStatic => const_eval_recursive_static,
             AssertFailure(x) => x.diagnostic_message(),
         }
     }
     fn add_args(self: Box<Self>, adder: &mut dyn FnMut(DiagnosticArgName, DiagnosticArgValue)) {
         use ConstEvalErrKind::*;
         match *self {
-            ConstAccessesMutGlobal | ModifiedGlobal => {}
+            RecursiveStatic | ConstAccessesMutGlobal | ModifiedGlobal => {}
             AssertFailure(kind) => kind.add_args(adder),
             Panic { msg, line, col, file } => {
                 adder("msg".into(), msg.into_diagnostic_arg());
diff --git a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
index c55d899e4d5..7099cdd5a75 100644
--- a/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
+++ b/compiler/rustc_const_eval/src/const_eval/eval_queries.rs
@@ -2,12 +2,12 @@ use either::{Left, Right};
 
 use rustc_hir::def::DefKind;
 use rustc_middle::mir::interpret::{AllocId, ErrorHandled, InterpErrorInfo};
-use rustc_middle::mir::pretty::write_allocation_bytes;
 use rustc_middle::mir::{self, ConstAlloc, ConstValue};
 use rustc_middle::traits::Reveal;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, TyCtxt};
+use rustc_span::def_id::LocalDefId;
 use rustc_span::Span;
 use rustc_target::abi::{self, Abi};
 
@@ -17,8 +17,9 @@ use crate::errors;
 use crate::errors::ConstEvalError;
 use crate::interpret::eval_nullary_intrinsic;
 use crate::interpret::{
-    intern_const_alloc_recursive, CtfeValidationMode, GlobalId, Immediate, InternKind, InterpCx,
-    InterpError, InterpResult, MPlaceTy, MemoryKind, OpTy, RefTracking, StackPopCleanup,
+    create_static_alloc, intern_const_alloc_recursive, take_static_root_alloc, CtfeValidationMode,
+    GlobalId, Immediate, InternKind, InterpCx, InterpError, InterpResult, MPlaceTy, MemoryKind,
+    OpTy, RefTracking, StackPopCleanup,
 };
 
 // Returns a pointer to where the result lives
@@ -46,7 +47,21 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     );
     let layout = ecx.layout_of(body.bound_return_ty().instantiate(tcx, cid.instance.args))?;
     assert!(layout.is_sized());
-    let ret = ecx.allocate(layout, MemoryKind::Stack)?;
+
+    let intern_kind = if cid.promoted.is_some() {
+        InternKind::Promoted
+    } else {
+        match tcx.static_mutability(cid.instance.def_id()) {
+            Some(m) => InternKind::Static(m),
+            None => InternKind::Constant,
+        }
+    };
+
+    let ret = if let InternKind::Static(_) = intern_kind {
+        create_static_alloc(ecx, cid.instance.def_id(), layout)?
+    } else {
+        ecx.allocate(layout, MemoryKind::Stack)?
+    };
 
     trace!(
         "eval_body_using_ecx: pushing stack frame for global: {}{}",
@@ -66,14 +81,6 @@ fn eval_body_using_ecx<'mir, 'tcx>(
     while ecx.step()? {}
 
     // Intern the result
-    let intern_kind = if cid.promoted.is_some() {
-        InternKind::Promoted
-    } else {
-        match tcx.static_mutability(cid.instance.def_id()) {
-            Some(m) => InternKind::Static(m),
-            None => InternKind::Constant,
-        }
-    };
     intern_const_alloc_recursive(ecx, intern_kind, &ret)?;
 
     Ok(ret)
@@ -250,10 +257,36 @@ pub fn eval_to_const_value_raw_provider<'tcx>(
 }
 
 #[instrument(skip(tcx), level = "debug")]
+pub fn eval_static_initializer_provider<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    def_id: LocalDefId,
+) -> ::rustc_middle::mir::interpret::EvalStaticInitializerRawResult<'tcx> {
+    assert!(tcx.is_static(def_id.to_def_id()));
+
+    let instance = ty::Instance::mono(tcx, def_id.to_def_id());
+    let cid = rustc_middle::mir::interpret::GlobalId { instance, promoted: None };
+    let mut ecx = InterpCx::new(
+        tcx,
+        tcx.def_span(def_id),
+        ty::ParamEnv::reveal_all(),
+        // Statics (and promoteds inside statics) may access other statics, because unlike consts
+        // they do not have to behave "as if" they were evaluated at runtime.
+        CompileTimeInterpreter::new(CanAccessMutGlobal::Yes, CheckAlignment::Error),
+    );
+    let alloc_id = eval_in_interpreter(&mut ecx, cid, true)?.alloc_id;
+    let alloc = take_static_root_alloc(&mut ecx, alloc_id);
+    let alloc = tcx.mk_const_alloc(alloc);
+    Ok(alloc)
+}
+
+#[instrument(skip(tcx), level = "debug")]
 pub fn eval_to_allocation_raw_provider<'tcx>(
     tcx: TyCtxt<'tcx>,
     key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>,
 ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
+    // This shouldn't be used for statics, since statics are conceptually places,
+    // not values -- so what we do here could break pointer identity.
+    assert!(key.value.promoted.is_some() || !tcx.is_static(key.value.instance.def_id()));
     // Const eval always happens in Reveal::All mode in order to be able to use the hidden types of
     // opaque types. This is needed for trivial things like `size_of`, but also for using associated
     // types that are not specified in the opaque type.
@@ -273,7 +306,7 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
     let def = cid.instance.def.def_id();
     let is_static = tcx.is_static(def);
 
-    let ecx = InterpCx::new(
+    let mut ecx = InterpCx::new(
         tcx,
         tcx.def_span(def),
         key.param_env,
@@ -283,11 +316,11 @@ pub fn eval_to_allocation_raw_provider<'tcx>(
         // so we have to reject reading mutable global memory.
         CompileTimeInterpreter::new(CanAccessMutGlobal::from(is_static), CheckAlignment::Error),
     );
-    eval_in_interpreter(ecx, cid, is_static)
+    eval_in_interpreter(&mut ecx, cid, is_static)
 }
 
 pub fn eval_in_interpreter<'mir, 'tcx>(
-    mut ecx: InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
+    ecx: &mut InterpCx<'mir, 'tcx, CompileTimeInterpreter<'mir, 'tcx>>,
     cid: GlobalId<'tcx>,
     is_static: bool,
 ) -> ::rustc_middle::mir::interpret::EvalToAllocationRawResult<'tcx> {
@@ -295,7 +328,7 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
     debug_assert_eq!(is_static, ecx.tcx.static_mutability(cid.instance.def_id()).is_some());
 
     let res = ecx.load_mir(cid.instance.def, cid.promoted);
-    match res.and_then(|body| eval_body_using_ecx(&mut ecx, cid, body)) {
+    match res.and_then(|body| eval_body_using_ecx(ecx, cid, body)) {
         Err(error) => {
             let (error, backtrace) = error.into_parts();
             backtrace.print_backtrace();
@@ -330,8 +363,11 @@ pub fn eval_in_interpreter<'mir, 'tcx>(
         }
         Ok(mplace) => {
             // Since evaluation had no errors, validate the resulting constant.
-            // This is a separate `try` block to provide more targeted error reporting.
+
+            // Temporarily allow access to the static_root_alloc_id for the purpose of validation.
+            let static_root_alloc_id = ecx.machine.static_root_alloc_id.take();
             let validation = const_validate_mplace(&ecx, &mplace, cid);
+            ecx.machine.static_root_alloc_id = static_root_alloc_id;
 
             let alloc_id = mplace.ptr().provenance.unwrap().alloc_id();
 
@@ -383,15 +419,9 @@ pub fn const_report_error<'mir, 'tcx>(
 
     let ub_note = matches!(error, InterpError::UndefinedBehavior(_)).then(|| {});
 
-    let alloc = ecx.tcx.global_alloc(alloc_id).unwrap_memory().inner();
-    let mut bytes = String::new();
-    if alloc.size() != abi::Size::ZERO {
-        bytes = "\n".into();
-        // FIXME(translation) there might be pieces that are translatable.
-        write_allocation_bytes(*ecx.tcx, alloc, &mut bytes, "    ").unwrap();
-    }
-    let raw_bytes =
-        errors::RawBytesNote { size: alloc.size().bytes(), align: alloc.align.bytes(), bytes };
+    let bytes = ecx.print_alloc_bytes_for_diagnostics(alloc_id);
+    let (size, align, _) = ecx.get_alloc_info(alloc_id);
+    let raw_bytes = errors::RawBytesNote { size: size.bytes(), align: align.bytes(), bytes };
 
     crate::const_eval::report(
         *ecx.tcx,
diff --git a/compiler/rustc_const_eval/src/const_eval/machine.rs b/compiler/rustc_const_eval/src/const_eval/machine.rs
index 5019bec388c..2c60ede7975 100644
--- a/compiler/rustc_const_eval/src/const_eval/machine.rs
+++ b/compiler/rustc_const_eval/src/const_eval/machine.rs
@@ -58,6 +58,9 @@ pub struct CompileTimeInterpreter<'mir, 'tcx> {
 
     /// Whether to check alignment during evaluation.
     pub(super) check_alignment: CheckAlignment,
+
+    /// Used to prevent reads from a static's base allocation, as that may allow for self-initialization.
+    pub(crate) static_root_alloc_id: Option<AllocId>,
 }
 
 #[derive(Copy, Clone)]
@@ -91,6 +94,7 @@ impl<'mir, 'tcx> CompileTimeInterpreter<'mir, 'tcx> {
             stack: Vec::new(),
             can_access_mut_global,
             check_alignment,
+            static_root_alloc_id: None,
         }
     }
 }
@@ -746,6 +750,17 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
         // Everything else is fine.
         Ok(())
     }
+
+    fn before_alloc_read(
+        ecx: &InterpCx<'mir, 'tcx, Self>,
+        alloc_id: AllocId,
+    ) -> InterpResult<'tcx> {
+        if Some(alloc_id) == ecx.machine.static_root_alloc_id {
+            Err(ConstEvalErrKind::RecursiveStatic.into())
+        } else {
+            Ok(())
+        }
+    }
 }
 
 // Please do not add any code below the above `Machine` trait impl. I (oli-obk) plan more cleanups
diff --git a/compiler/rustc_const_eval/src/interpret/cast.rs b/compiler/rustc_const_eval/src/interpret/cast.rs
index 6d470ff162e..a88e130cd4b 100644
--- a/compiler/rustc_const_eval/src/interpret/cast.rs
+++ b/compiler/rustc_const_eval/src/interpret/cast.rs
@@ -153,7 +153,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     );
                 }
 
-                self.copy_op(src, dest, /*allow_transmute*/ true)?;
+                self.copy_op_allow_transmute(src, dest)?;
             }
         }
         Ok(())
@@ -441,7 +441,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     if src_field.layout.is_1zst() && cast_ty_field.is_1zst() {
                         // Skip 1-ZST fields.
                     } else if src_field.layout.ty == cast_ty_field.ty {
-                        self.copy_op(&src_field, &dst_field, /*allow_transmute*/ false)?;
+                        self.copy_op(&src_field, &dst_field)?;
                     } else {
                         if found_cast_field {
                             span_bug!(self.cur_span(), "unsize_into: more than one field to cast");
diff --git a/compiler/rustc_const_eval/src/interpret/eval_context.rs b/compiler/rustc_const_eval/src/interpret/eval_context.rs
index 8af69220e03..517994d4741 100644
--- a/compiler/rustc_const_eval/src/interpret/eval_context.rs
+++ b/compiler/rustc_const_eval/src/interpret/eval_context.rs
@@ -899,7 +899,19 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 .local_to_op(self.frame(), mir::RETURN_PLACE, None)
                 .expect("return place should always be live");
             let dest = self.frame().return_place.clone();
-            let err = self.copy_op(&op, &dest, /*allow_transmute*/ true);
+            let err = if self.stack().len() == 1 {
+                // The initializer of constants and statics will get validated separately
+                // after the constant has been fully evaluated. While we could fall back to the default
+                // code path, that will cause -Zenforce-validity to cycle on static initializers.
+                // Reading from a static's memory is not allowed during its evaluation, and will always
+                // trigger a cycle error. Validation must read from the memory of the current item.
+                // For Miri this means we do not validate the root frame return value,
+                // but Miri anyway calls `read_target_isize` on that so separate validation
+                // is not needed.
+                self.copy_op_no_dest_validation(&op, &dest)
+            } else {
+                self.copy_op_allow_transmute(&op, &dest)
+            };
             trace!("return value: {:?}", self.dump_place(&dest));
             // We delay actually short-circuiting on this error until *after* the stack frame is
             // popped, since we want this error to be attributed to the caller, whose type defines
diff --git a/compiler/rustc_const_eval/src/interpret/intern.rs b/compiler/rustc_const_eval/src/interpret/intern.rs
index 7feac6156bc..959ec2ca865 100644
--- a/compiler/rustc_const_eval/src/interpret/intern.rs
+++ b/compiler/rustc_const_eval/src/interpret/intern.rs
@@ -85,6 +85,8 @@ pub enum InternKind {
 ///
 /// This *cannot raise an interpreter error*. Doing so is left to validation, which
 /// tracks where in the value we are and thus can show much better error messages.
+///
+/// For `InternKind::Static` the root allocation will not be interned, but must be handled by the caller.
 #[instrument(level = "debug", skip(ecx))]
 pub fn intern_const_alloc_recursive<
     'mir,
@@ -97,12 +99,12 @@ pub fn intern_const_alloc_recursive<
 ) -> Result<(), ErrorGuaranteed> {
     // We are interning recursively, and for mutability we are distinguishing the "root" allocation
     // that we are starting in, and all other allocations that we are encountering recursively.
-    let (base_mutability, inner_mutability) = match intern_kind {
+    let (base_mutability, inner_mutability, is_static) = match intern_kind {
         InternKind::Constant | InternKind::Promoted => {
             // Completely immutable. Interning anything mutably here can only lead to unsoundness,
             // since all consts are conceptually independent values but share the same underlying
             // memory.
-            (Mutability::Not, Mutability::Not)
+            (Mutability::Not, Mutability::Not, false)
         }
         InternKind::Static(Mutability::Not) => {
             (
@@ -115,22 +117,31 @@ pub fn intern_const_alloc_recursive<
                 // Inner allocations are never mutable. They can only arise via the "tail
                 // expression" / "outer scope" rule, and we treat them consistently with `const`.
                 Mutability::Not,
+                true,
             )
         }
         InternKind::Static(Mutability::Mut) => {
             // Just make everything mutable. We accept code like
             // `static mut X = &mut [42]`, so even inner allocations need to be mutable.
-            (Mutability::Mut, Mutability::Mut)
+            (Mutability::Mut, Mutability::Mut, true)
         }
     };
 
     // Intern the base allocation, and initialize todo list for recursive interning.
     let base_alloc_id = ret.ptr().provenance.unwrap().alloc_id();
+    trace!(?base_alloc_id, ?base_mutability);
     // First we intern the base allocation, as it requires a different mutability.
     // This gives us the initial set of nested allocations, which will then all be processed
     // recursively in the loop below.
-    let mut todo: Vec<_> =
-        intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect();
+    let mut todo: Vec<_> = if is_static {
+        // Do not steal the root allocation, we need it later for `take_static_root_alloc`
+        // But still change its mutability to match the requested one.
+        let alloc = ecx.memory.alloc_map.get_mut(&base_alloc_id).unwrap();
+        alloc.1.mutability = base_mutability;
+        alloc.1.provenance().ptrs().iter().map(|&(_, prov)| prov).collect()
+    } else {
+        intern_shallow(ecx, base_alloc_id, base_mutability).unwrap().map(|prov| prov).collect()
+    };
     // We need to distinguish "has just been interned" from "was already in `tcx`",
     // so we track this in a separate set.
     let mut just_interned: FxHashSet<_> = std::iter::once(base_alloc_id).collect();
@@ -148,7 +159,17 @@ pub fn intern_const_alloc_recursive<
     // before validation, and interning doesn't know the type of anything, this means we can't show
     // better errors. Maybe we should consider doing validation before interning in the future.
     while let Some(prov) = todo.pop() {
+        trace!(?prov);
         let alloc_id = prov.alloc_id();
+
+        if base_alloc_id == alloc_id && is_static {
+            // This is a pointer to the static itself. It's ok for a static to refer to itself,
+            // even mutably. Whether that mutable pointer is legal at all is checked in validation.
+            // See tests/ui/statics/recursive_interior_mut.rs for how such a situation can occur.
+            // We also already collected all the nested allocations, so there's no need to do that again.
+            continue;
+        }
+
         // Crucially, we check this *before* checking whether the `alloc_id`
         // has already been interned. The point of this check is to ensure that when
         // there are multiple pointers to the same allocation, they are *all* immutable.
@@ -176,6 +197,7 @@ pub fn intern_const_alloc_recursive<
             // `&None::<Cell<i32>>` lead to promotion that can produce mutable pointers. We rely
             // on the promotion analysis not screwing up to ensure that it is sound to intern
             // promoteds as immutable.
+            trace!("found bad mutable pointer");
             found_bad_mutable_pointer = true;
         }
         if ecx.tcx.try_get_global_alloc(alloc_id).is_some() {
diff --git a/compiler/rustc_const_eval/src/interpret/intrinsics.rs b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
index 7991f90b815..f020616f6d8 100644
--- a/compiler/rustc_const_eval/src/interpret/intrinsics.rs
+++ b/compiler/rustc_const_eval/src/interpret/intrinsics.rs
@@ -120,7 +120,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let val = self.tcx.span_as_caller_location(span);
                 let val =
                     self.const_val_to_op(val, self.tcx.caller_location_ty(), Some(dest.layout))?;
-                self.copy_op(&val, dest, /* allow_transmute */ false)?;
+                self.copy_op(&val, dest)?;
             }
 
             sym::min_align_of_val | sym::size_of_val => {
@@ -157,7 +157,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     tcx.const_eval_global_id(self.param_env, gid, Some(tcx.span))
                 })?;
                 let val = self.const_val_to_op(val, ty, Some(dest.layout))?;
-                self.copy_op(&val, dest, /*allow_transmute*/ false)?;
+                self.copy_op(&val, dest)?;
             }
 
             sym::ctpop
@@ -391,7 +391,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     } else {
                         self.project_index(&input, i)?.into()
                     };
-                    self.copy_op(&value, &place, /*allow_transmute*/ false)?;
+                    self.copy_op(&value, &place)?;
                 }
             }
             sym::simd_extract => {
@@ -401,15 +401,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                     index < input_len,
                     "index `{index}` must be in bounds of vector with length {input_len}"
                 );
-                self.copy_op(
-                    &self.project_index(&input, index)?,
-                    dest,
-                    /*allow_transmute*/ false,
-                )?;
+                self.copy_op(&self.project_index(&input, index)?, dest)?;
             }
             sym::likely | sym::unlikely | sym::black_box => {
                 // These just return their argument
-                self.copy_op(&args[0], dest, /*allow_transmute*/ false)?;
+                self.copy_op(&args[0], dest)?;
             }
             sym::raw_eq => {
                 let result = self.raw_eq_intrinsic(&args[0], &args[1])?;
diff --git a/compiler/rustc_const_eval/src/interpret/machine.rs b/compiler/rustc_const_eval/src/interpret/machine.rs
index b981a1ee2ca..0106ec425bc 100644
--- a/compiler/rustc_const_eval/src/interpret/machine.rs
+++ b/compiler/rustc_const_eval/src/interpret/machine.rs
@@ -388,6 +388,8 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
     /// Takes read-only access to the allocation so we can keep all the memory read
     /// operations take `&self`. Use a `RefCell` in `AllocExtra` if you
     /// need to mutate.
+    ///
+    /// This is not invoked for ZST accesses, as no read actually happens.
     #[inline(always)]
     fn before_memory_read(
         _tcx: TyCtxtAt<'tcx>,
@@ -399,7 +401,20 @@ pub trait Machine<'mir, 'tcx: 'mir>: Sized {
         Ok(())
     }
 
+    /// Hook for performing extra checks on any memory read access,
+    /// that involves an allocation, even ZST reads.
+    ///
+    /// Used to prevent statics from self-initializing by reading from their own memory
+    /// as it is being initialized.
+    fn before_alloc_read(
+        _ecx: &InterpCx<'mir, 'tcx, Self>,
+        _alloc_id: AllocId,
+    ) -> InterpResult<'tcx> {
+        Ok(())
+    }
+
     /// Hook for performing extra checks on a memory write access.
+    /// This is not invoked for ZST accesses, as no write actually happens.
     #[inline(always)]
     fn before_memory_write(
         _tcx: TyCtxtAt<'tcx>,
diff --git a/compiler/rustc_const_eval/src/interpret/memory.rs b/compiler/rustc_const_eval/src/interpret/memory.rs
index 4acf4ed893c..3b2208b8caa 100644
--- a/compiler/rustc_const_eval/src/interpret/memory.rs
+++ b/compiler/rustc_const_eval/src/interpret/memory.rs
@@ -13,7 +13,7 @@ use std::fmt;
 use std::ptr;
 
 use rustc_ast::Mutability;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_middle::mir::display_allocation;
 use rustc_middle::ty::{self, Instance, ParamEnv, Ty, TyCtxt};
 use rustc_target::abi::{Align, HasDataLayout, Size};
@@ -104,13 +104,13 @@ pub struct Memory<'mir, 'tcx, M: Machine<'mir, 'tcx>> {
     pub(super) alloc_map: M::MemoryMap,
 
     /// Map for "extra" function pointers.
-    extra_fn_ptr_map: FxHashMap<AllocId, M::ExtraFnVal>,
+    extra_fn_ptr_map: FxIndexMap<AllocId, M::ExtraFnVal>,
 
     /// To be able to compare pointers with null, and to check alignment for accesses
     /// to ZSTs (where pointers may dangle), we keep track of the size even for allocations
     /// that do not exist any more.
     // FIXME: this should not be public, but interning currently needs access to it
-    pub(super) dead_alloc_map: FxHashMap<AllocId, (Size, Align)>,
+    pub(super) dead_alloc_map: FxIndexMap<AllocId, (Size, Align)>,
 }
 
 /// A reference to some allocation that was already bounds-checked for the given region
@@ -135,8 +135,8 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> Memory<'mir, 'tcx, M> {
     pub fn new() -> Self {
         Memory {
             alloc_map: M::MemoryMap::default(),
-            extra_fn_ptr_map: FxHashMap::default(),
-            dead_alloc_map: FxHashMap::default(),
+            extra_fn_ptr_map: FxIndexMap::default(),
+            dead_alloc_map: FxIndexMap::default(),
         }
     }
 
@@ -624,19 +624,20 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             size,
             CheckInAllocMsg::MemoryAccessTest,
             |alloc_id, offset, prov| {
+                // We want to call the hook on *all* accesses that involve an AllocId,
+                // including zero-sized accesses. That means we have to do it here
+                // rather than below in the `Some` branch.
+                M::before_alloc_read(self, alloc_id)?;
                 let alloc = self.get_alloc_raw(alloc_id)?;
                 Ok((alloc.size(), alloc.align, (alloc_id, offset, prov, alloc)))
             },
         )?;
+
         if let Some((alloc_id, offset, prov, alloc)) = ptr_and_alloc {
             let range = alloc_range(offset, size);
             M::before_memory_read(self.tcx, &self.machine, &alloc.extra, (alloc_id, prov), range)?;
             Ok(Some(AllocRef { alloc, range, tcx: *self.tcx, alloc_id }))
         } else {
-            // Even in this branch we have to be sure that we actually access the allocation, in
-            // order to ensure that `static FOO: Type = FOO;` causes a cycle error instead of
-            // magically pulling *any* ZST value from the ether. However, the `get_raw` above is
-            // always called when `ptr` has an `AllocId`.
             Ok(None)
         }
     }
@@ -855,6 +856,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         DumpAllocs { ecx: self, allocs }
     }
 
+    /// Print the allocation's bytes, without any nested allocations.
+    pub fn print_alloc_bytes_for_diagnostics(&self, id: AllocId) -> String {
+        // Using the "raw" access to avoid the `before_alloc_read` hook, we specifically
+        // want to be able to read all memory for diagnostics, even if that is cyclic.
+        let alloc = self.get_alloc_raw(id).unwrap();
+        let mut bytes = String::new();
+        if alloc.size() != Size::ZERO {
+            bytes = "\n".into();
+            // FIXME(translation) there might be pieces that are translatable.
+            rustc_middle::mir::pretty::write_allocation_bytes(*self.tcx, alloc, &mut bytes, "    ")
+                .unwrap();
+        }
+        bytes
+    }
+
     /// Find leaked allocations. Allocations reachable from `static_roots` or a `Global` allocation
     /// are not considered leaked, as well as leaks whose kind's `may_leak()` returns true.
     pub fn find_leaked_allocations(
diff --git a/compiler/rustc_const_eval/src/interpret/mod.rs b/compiler/rustc_const_eval/src/interpret/mod.rs
index c1b6ce4eb4e..a15e52d07e6 100644
--- a/compiler/rustc_const_eval/src/interpret/mod.rs
+++ b/compiler/rustc_const_eval/src/interpret/mod.rs
@@ -39,4 +39,5 @@ use self::{
 };
 
 pub(crate) use self::intrinsics::eval_nullary_intrinsic;
+pub(crate) use self::util::{create_static_alloc, take_static_root_alloc};
 use eval_context::{from_known_layout, mir_assign_valid_types};
diff --git a/compiler/rustc_const_eval/src/interpret/place.rs b/compiler/rustc_const_eval/src/interpret/place.rs
index 03d1dc9fd3d..6e987784ff9 100644
--- a/compiler/rustc_const_eval/src/interpret/place.rs
+++ b/compiler/rustc_const_eval/src/interpret/place.rs
@@ -759,14 +759,57 @@ where
     }
 
     /// Copies the data from an operand to a place.
+    /// The layouts of the `src` and `dest` may disagree.
+    /// Does not perform validation of the destination.
+    /// The only known use case for this function is checking the return
+    /// value of a static during stack frame popping.
+    #[inline(always)]
+    pub(super) fn copy_op_no_dest_validation(
+        &mut self,
+        src: &impl Readable<'tcx, M::Provenance>,
+        dest: &impl Writeable<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx> {
+        self.copy_op_inner(
+            src, dest, /* allow_transmute */ true, /* validate_dest */ false,
+        )
+    }
+
+    /// Copies the data from an operand to a place.
+    /// The layouts of the `src` and `dest` may disagree.
+    #[inline(always)]
+    pub fn copy_op_allow_transmute(
+        &mut self,
+        src: &impl Readable<'tcx, M::Provenance>,
+        dest: &impl Writeable<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx> {
+        self.copy_op_inner(
+            src, dest, /* allow_transmute */ true, /* validate_dest */ true,
+        )
+    }
+
+    /// Copies the data from an operand to a place.
+    /// `src` and `dest` must have the same layout and the copied value will be validated.
+    #[inline(always)]
+    pub fn copy_op(
+        &mut self,
+        src: &impl Readable<'tcx, M::Provenance>,
+        dest: &impl Writeable<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx> {
+        self.copy_op_inner(
+            src, dest, /* allow_transmute */ false, /* validate_dest */ true,
+        )
+    }
+
+    /// Copies the data from an operand to a place.
     /// `allow_transmute` indicates whether the layouts may disagree.
     #[inline(always)]
     #[instrument(skip(self), level = "debug")]
-    pub fn copy_op(
+    fn copy_op_inner(
         &mut self,
         src: &impl Readable<'tcx, M::Provenance>,
         dest: &impl Writeable<'tcx, M::Provenance>,
         allow_transmute: bool,
+        validate_dest: bool,
     ) -> InterpResult<'tcx> {
         // Generally for transmutation, data must be valid both at the old and new type.
         // But if the types are the same, the 2nd validation below suffices.
@@ -777,7 +820,7 @@ where
         // Do the actual copy.
         self.copy_op_no_validate(src, dest, allow_transmute)?;
 
-        if M::enforce_validity(self, dest.layout()) {
+        if validate_dest && M::enforce_validity(self, dest.layout()) {
             // Data got changed, better make sure it matches the type!
             self.validate_operand(&dest.to_op(self)?)?;
         }
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 23f3d7eb67d..d4c96f4573d 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -151,12 +151,12 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             Use(ref operand) => {
                 // Avoid recomputing the layout
                 let op = self.eval_operand(operand, Some(dest.layout))?;
-                self.copy_op(&op, &dest, /*allow_transmute*/ false)?;
+                self.copy_op(&op, &dest)?;
             }
 
             CopyForDeref(place) => {
                 let op = self.eval_place_to_op(place, Some(dest.layout))?;
-                self.copy_op(&op, &dest, /* allow_transmute*/ false)?;
+                self.copy_op(&op, &dest)?;
             }
 
             BinaryOp(bin_op, box (ref left, ref right)) => {
@@ -316,7 +316,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
             let field_index = active_field_index.unwrap_or(field_index);
             let field_dest = self.project_field(&variant_dest, field_index.as_usize())?;
             let op = self.eval_operand(operand, Some(field_dest.layout))?;
-            self.copy_op(&op, &field_dest, /*allow_transmute*/ false)?;
+            self.copy_op(&op, &field_dest)?;
         }
         self.write_discriminant(variant_index, dest)
     }
@@ -339,7 +339,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         } else {
             // Write the src to the first element.
             let first = self.project_index(&dest, 0)?;
-            self.copy_op(&src, &first, /*allow_transmute*/ false)?;
+            self.copy_op(&src, &first)?;
 
             // This is performance-sensitive code for big static/const arrays! So we
             // avoid writing each operand individually and instead just make many copies
diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs
index 4037220e5ed..b2207c3d310 100644
--- a/compiler/rustc_const_eval/src/interpret/terminator.rs
+++ b/compiler/rustc_const_eval/src/interpret/terminator.rs
@@ -481,7 +481,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         // FIXME: Depending on the PassMode, this should reset some padding to uninitialized. (This
         // is true for all `copy_op`, but there are a lot of special cases for argument passing
         // specifically.)
-        self.copy_op(&caller_arg_copy, &callee_arg, /*allow_transmute*/ true)?;
+        self.copy_op_allow_transmute(&caller_arg_copy, &callee_arg)?;
         // If this was an in-place pass, protect the place it comes from for the duration of the call.
         if let FnArg::InPlace(place) = caller_arg {
             M::protect_in_place_function_argument(self, place)?;
diff --git a/compiler/rustc_const_eval/src/interpret/util.rs b/compiler/rustc_const_eval/src/interpret/util.rs
index 3a9ee904734..2a13671a829 100644
--- a/compiler/rustc_const_eval/src/interpret/util.rs
+++ b/compiler/rustc_const_eval/src/interpret/util.rs
@@ -1,9 +1,15 @@
-use rustc_middle::mir::interpret::InterpResult;
+use crate::const_eval::CompileTimeEvalContext;
+use crate::interpret::{MemPlaceMeta, MemoryKind};
+use rustc_middle::mir::interpret::{AllocId, Allocation, InterpResult, Pointer};
+use rustc_middle::ty::layout::TyAndLayout;
 use rustc_middle::ty::{
     self, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
 };
+use rustc_span::def_id::DefId;
 use std::ops::ControlFlow;
 
+use super::MPlaceTy;
+
 /// Checks whether a type contains generic parameters which must be instantiated.
 ///
 /// In case it does, returns a `TooGeneric` const eval error. Note that due to polymorphization
@@ -73,3 +79,23 @@ where
         Ok(())
     }
 }
+
+pub(crate) fn take_static_root_alloc<'mir, 'tcx: 'mir>(
+    ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
+    alloc_id: AllocId,
+) -> Allocation {
+    ecx.memory.alloc_map.swap_remove(&alloc_id).unwrap().1
+}
+
+pub(crate) fn create_static_alloc<'mir, 'tcx: 'mir>(
+    ecx: &mut CompileTimeEvalContext<'mir, 'tcx>,
+    static_def_id: DefId,
+    layout: TyAndLayout<'tcx>,
+) -> InterpResult<'tcx, MPlaceTy<'tcx>> {
+    let alloc = Allocation::try_uninit(layout.size, layout.align.abi)?;
+    let alloc_id = ecx.tcx.reserve_and_set_static_alloc(static_def_id);
+    assert_eq!(ecx.machine.static_root_alloc_id, None);
+    ecx.machine.static_root_alloc_id = Some(alloc_id);
+    assert!(ecx.memory.alloc_map.insert(alloc_id, (MemoryKind::Stack, alloc)).is_none());
+    Ok(ecx.ptr_with_meta_to_mplace(Pointer::from(alloc_id).into(), MemPlaceMeta::None, layout))
+}
diff --git a/compiler/rustc_const_eval/src/interpret/validity.rs b/compiler/rustc_const_eval/src/interpret/validity.rs
index eb9f3fee165..08a2e38bfa1 100644
--- a/compiler/rustc_const_eval/src/interpret/validity.rs
+++ b/compiler/rustc_const_eval/src/interpret/validity.rs
@@ -27,9 +27,9 @@ use rustc_target::abi::{
 use std::hash::Hash;
 
 use super::{
-    format_interp_error, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy, Immediate, InterpCx,
-    InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable, Scalar,
-    ValueVisitor,
+    format_interp_error, machine::AllocMap, AllocId, CheckInAllocMsg, GlobalAlloc, ImmTy,
+    Immediate, InterpCx, InterpResult, MPlaceTy, Machine, MemPlaceMeta, OpTy, Pointer, Projectable,
+    Scalar, ValueVisitor,
 };
 
 // for the validation errors
@@ -712,11 +712,14 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
     fn in_mutable_memory(&self, op: &OpTy<'tcx, M::Provenance>) -> bool {
         if let Some(mplace) = op.as_mplace_or_imm().left() {
             if let Some(alloc_id) = mplace.ptr().provenance.and_then(|p| p.get_alloc_id()) {
-                if self.ecx.tcx.global_alloc(alloc_id).unwrap_memory().inner().mutability
-                    == Mutability::Mut
-                {
-                    return true;
-                }
+                let mutability = match self.ecx.tcx.global_alloc(alloc_id) {
+                    GlobalAlloc::Static(_) => {
+                        self.ecx.memory.alloc_map.get(alloc_id).unwrap().1.mutability
+                    }
+                    GlobalAlloc::Memory(alloc) => alloc.inner().mutability,
+                    _ => span_bug!(self.ecx.tcx.span, "not a memory allocation"),
+                };
+                return mutability == Mutability::Mut;
             }
         }
         false
diff --git a/compiler/rustc_const_eval/src/lib.rs b/compiler/rustc_const_eval/src/lib.rs
index 839cfd8d85a..e33f374c359 100644
--- a/compiler/rustc_const_eval/src/lib.rs
+++ b/compiler/rustc_const_eval/src/lib.rs
@@ -40,6 +40,7 @@ pub fn provide(providers: &mut Providers) {
     const_eval::provide(providers);
     providers.eval_to_const_value_raw = const_eval::eval_to_const_value_raw_provider;
     providers.eval_to_allocation_raw = const_eval::eval_to_allocation_raw_provider;
+    providers.eval_static_initializer = const_eval::eval_static_initializer_provider;
     providers.hooks.const_caller_location = util::caller_location::const_caller_location_provider;
     providers.eval_to_valtree = |tcx, param_env_and_value| {
         let (param_env, raw) = param_env_and_value.into_parts();
diff --git a/compiler/rustc_data_structures/src/unord.rs b/compiler/rustc_data_structures/src/unord.rs
index 907c866b3ed..a99e2062039 100644
--- a/compiler/rustc_data_structures/src/unord.rs
+++ b/compiler/rustc_data_structures/src/unord.rs
@@ -524,6 +524,11 @@ impl<K: Eq + Hash, V> UnordMap<K, V> {
         UnordItems(self.inner.into_iter())
     }
 
+    #[inline]
+    pub fn keys(&self) -> UnordItems<&K, impl Iterator<Item = &K>> {
+        UnordItems(self.inner.keys())
+    }
+
     /// Returns the entries of this map in stable sort order (as defined by `ToStableHashKey`).
     ///
     /// The `cache_sort_key` parameter controls if [slice::sort_by_cached_key] or
diff --git a/compiler/rustc_errors/src/diagnostic.rs b/compiler/rustc_errors/src/diagnostic.rs
index b14a12175c7..91a8ec3b794 100644
--- a/compiler/rustc_errors/src/diagnostic.rs
+++ b/compiler/rustc_errors/src/diagnostic.rs
@@ -3,7 +3,7 @@ use crate::{
     CodeSuggestion, DiagnosticBuilder, DiagnosticMessage, EmissionGuarantee, ErrCode, Level,
     MultiSpan, SubdiagnosticMessage, Substitution, SubstitutionPart, SuggestionStyle,
 };
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap};
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_error_messages::fluent_value_from_str_list_sep_by_and;
 use rustc_error_messages::FluentValue;
 use rustc_lint_defs::{Applicability, LintExpectationId};
@@ -105,7 +105,7 @@ pub struct Diagnostic {
     pub span: MultiSpan,
     pub children: Vec<SubDiagnostic>,
     pub suggestions: Result<Vec<CodeSuggestion>, SuggestionsDisabled>,
-    args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>,
+    args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue>,
 
     /// This is not used for highlighting or rendering any error message. Rather, it can be used
     /// as a sort key to sort a buffer of diagnostics. By default, it is the primary span of
@@ -898,9 +898,6 @@ impl Diagnostic {
         self
     }
 
-    // Exact iteration order of diagnostic arguments shouldn't make a difference to output because
-    // they're only used in interpolation.
-    #[allow(rustc::potential_query_instability)]
     pub fn args(&self) -> impl Iterator<Item = DiagnosticArg<'_>> {
         self.args.iter()
     }
@@ -914,7 +911,7 @@ impl Diagnostic {
         self
     }
 
-    pub fn replace_args(&mut self, args: FxHashMap<DiagnosticArgName, DiagnosticArgValue>) {
+    pub fn replace_args(&mut self, args: FxIndexMap<DiagnosticArgName, DiagnosticArgValue>) {
         self.args = args;
     }
 
diff --git a/compiler/rustc_errors/src/emitter.rs b/compiler/rustc_errors/src/emitter.rs
index 38c6661377b..afb1b854e72 100644
--- a/compiler/rustc_errors/src/emitter.rs
+++ b/compiler/rustc_errors/src/emitter.rs
@@ -1743,9 +1743,17 @@ impl HumanEmitter {
         buffer.append(0, level.to_str(), Style::Level(*level));
         buffer.append(0, ": ", Style::HeaderMsg);
 
+        let mut msg = vec![(suggestion.msg.to_owned(), Style::NoStyle)];
+        if suggestions
+            .iter()
+            .take(MAX_SUGGESTIONS)
+            .any(|(_, _, _, only_capitalization)| *only_capitalization)
+        {
+            msg.push((" (notice the capitalization difference)".into(), Style::NoStyle));
+        }
         self.msgs_to_buffer(
             &mut buffer,
-            &[(suggestion.msg.to_owned(), Style::NoStyle)],
+            &msg,
             args,
             max_line_num_len,
             "suggestion",
@@ -1754,12 +1762,8 @@ impl HumanEmitter {
 
         let mut row_num = 2;
         draw_col_separator_no_space(&mut buffer, 1, max_line_num_len + 1);
-        let mut notice_capitalization = false;
-        for (complete, parts, highlights, only_capitalization) in
-            suggestions.iter().take(MAX_SUGGESTIONS)
-        {
+        for (complete, parts, highlights, _) in suggestions.iter().take(MAX_SUGGESTIONS) {
             debug!(?complete, ?parts, ?highlights);
-            notice_capitalization |= only_capitalization;
 
             let has_deletion = parts.iter().any(|p| p.is_deletion(sm));
             let is_multiline = complete.lines().count() > 1;
@@ -2058,9 +2062,6 @@ impl HumanEmitter {
             let others = suggestions.len() - MAX_SUGGESTIONS;
             let msg = format!("and {} other candidate{}", others, pluralize!(others));
             buffer.puts(row_num, max_line_num_len + 3, &msg, Style::NoStyle);
-        } else if notice_capitalization {
-            let msg = "notice the capitalization difference";
-            buffer.puts(row_num, max_line_num_len + 3, msg, Style::NoStyle);
         }
         emit_to_destination(&buffer.render(), level, &mut self.dst, self.short_message)?;
         Ok(())
diff --git a/compiler/rustc_errors/src/lib.rs b/compiler/rustc_errors/src/lib.rs
index d876f28040d..b0db3545ae7 100644
--- a/compiler/rustc_errors/src/lib.rs
+++ b/compiler/rustc_errors/src/lib.rs
@@ -320,7 +320,9 @@ impl CodeSuggestion {
                 // We need to keep track of the difference between the existing code and the added
                 // or deleted code in order to point at the correct column *after* substitution.
                 let mut acc = 0;
+                let mut only_capitalization = false;
                 for part in &substitution.parts {
+                    only_capitalization |= is_case_difference(sm, &part.snippet, part.span);
                     let cur_lo = sm.lookup_char_pos(part.span.lo());
                     if prev_hi.line == cur_lo.line {
                         let mut count =
@@ -393,7 +395,6 @@ impl CodeSuggestion {
                     }
                 }
                 highlights.push(std::mem::take(&mut line_highlight));
-                let only_capitalization = is_case_difference(sm, &buf, bounding_span);
                 // if the replacement already ends with a newline, don't print the next line
                 if !buf.ends_with('\n') {
                     push_trailing(&mut buf, prev_line.as_ref(), &prev_hi, None);
diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs
index cfeb31fc4c8..09144523658 100644
--- a/compiler/rustc_expand/src/base.rs
+++ b/compiler/rustc_expand/src/base.rs
@@ -567,10 +567,13 @@ impl DummyResult {
     }
 
     /// A plain dummy type.
-    pub fn raw_ty(sp: Span, is_error: bool) -> P<ast::Ty> {
+    pub fn raw_ty(sp: Span) -> P<ast::Ty> {
+        // FIXME(nnethercote): you might expect `ast::TyKind::Dummy` to be used here, but some
+        // values produced here end up being lowered to HIR, which `ast::TyKind::Dummy` does not
+        // support, so we use an empty tuple instead.
         P(ast::Ty {
             id: ast::DUMMY_NODE_ID,
-            kind: if is_error { ast::TyKind::Err } else { ast::TyKind::Tup(ThinVec::new()) },
+            kind: ast::TyKind::Tup(ThinVec::new()),
             span: sp,
             tokens: None,
         })
@@ -611,7 +614,7 @@ impl MacResult for DummyResult {
     }
 
     fn make_ty(self: Box<DummyResult>) -> Option<P<ast::Ty>> {
-        Some(DummyResult::raw_ty(self.span, self.is_error))
+        Some(DummyResult::raw_ty(self.span))
     }
 
     fn make_arms(self: Box<DummyResult>) -> Option<SmallVec<[ast::Arm; 1]>> {
@@ -1266,7 +1269,7 @@ pub fn expr_to_spanned_string<'a>(
                 );
                 Some((err, true))
             }
-            Ok(ast::LitKind::Err) => None,
+            Ok(ast::LitKind::Err(_)) => None,
             Err(err) => {
                 report_lit_error(&cx.sess.parse_sess, err, token_lit, expr.span);
                 None
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs
index 3a78bd94505..8f31b5801da 100644
--- a/compiler/rustc_expand/src/proc_macro_server.rs
+++ b/compiler/rustc_expand/src/proc_macro_server.rs
@@ -10,7 +10,7 @@ use rustc_ast::util::literal::escape_byte_str_symbol;
 use rustc_ast_pretty::pprust;
 use rustc_data_structures::fx::FxHashMap;
 use rustc_data_structures::sync::Lrc;
-use rustc_errors::{MultiSpan, PResult};
+use rustc_errors::{ErrorGuaranteed, MultiSpan, PResult};
 use rustc_parse::lexer::nfc_normalize;
 use rustc_parse::parse_stream_from_source_str;
 use rustc_session::parse::ParseSess;
@@ -63,7 +63,12 @@ impl FromInternal<token::LitKind> for LitKind {
             token::ByteStrRaw(n) => LitKind::ByteStrRaw(n),
             token::CStr => LitKind::CStr,
             token::CStrRaw(n) => LitKind::CStrRaw(n),
-            token::Err => LitKind::Err,
+            token::Err(_guar) => {
+                // This is the only place a `pm::bridge::LitKind::ErrWithGuar`
+                // is constructed. Note that an `ErrorGuaranteed` is available,
+                // as required. See the comment in `to_internal`.
+                LitKind::ErrWithGuar
+            }
             token::Bool => unreachable!(),
         }
     }
@@ -82,7 +87,16 @@ impl ToInternal<token::LitKind> for LitKind {
             LitKind::ByteStrRaw(n) => token::ByteStrRaw(n),
             LitKind::CStr => token::CStr,
             LitKind::CStrRaw(n) => token::CStrRaw(n),
-            LitKind::Err => token::Err,
+            LitKind::ErrWithGuar => {
+                // This is annoying but valid. `LitKind::ErrWithGuar` would
+                // have an `ErrorGuaranteed` except that type isn't available
+                // in that crate. So we have to fake one. And we don't want to
+                // use a delayed bug because there might be lots of these,
+                // which would be expensive.
+                #[allow(deprecated)]
+                let guar = ErrorGuaranteed::unchecked_error_guaranteed();
+                token::Err(guar)
+            }
         }
     }
 }
@@ -477,7 +491,7 @@ impl server::FreeFunctions for Rustc<'_, '_> {
                 | token::LitKind::ByteStrRaw(_)
                 | token::LitKind::CStr
                 | token::LitKind::CStrRaw(_)
-                | token::LitKind::Err => return Err(()),
+                | token::LitKind::Err(_) => return Err(()),
                 token::LitKind::Integer | token::LitKind::Float => {}
             }
 
diff --git a/compiler/rustc_hir_analysis/src/astconv/bounds.rs b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
index 7157382c883..dab1e2d5253 100644
--- a/compiler/rustc_hir_analysis/src/astconv/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/bounds.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -241,7 +241,7 @@ impl<'tcx> dyn AstConv<'tcx> + '_ {
         binding: &ConvertedBinding<'_, 'tcx>,
         bounds: &mut Bounds<'tcx>,
         speculative: bool,
-        dup_bindings: &mut FxHashMap<DefId, Span>,
+        dup_bindings: &mut FxIndexMap<DefId, Span>,
         path_span: Span,
         only_self_bounds: OnlySelfBounds,
     ) -> Result<(), ErrorGuaranteed> {
diff --git a/compiler/rustc_hir_analysis/src/astconv/errors.rs b/compiler/rustc_hir_analysis/src/astconv/errors.rs
index 3c64b102bae..ea8d364bba6 100644
--- a/compiler/rustc_hir_analysis/src/astconv/errors.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/errors.rs
@@ -5,7 +5,7 @@ use crate::errors::{
 };
 use crate::fluent_generated as fluent;
 use crate::traits::error_reporting::report_object_safety_error;
-use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
+use rustc_data_structures::fx::{FxIndexMap, FxIndexSet};
 use rustc_data_structures::sorted_map::SortedMap;
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{
@@ -806,7 +806,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         if suggestions.len() != 1 || already_has_generics_args_suggestion {
             // We don't need this label if there's an inline suggestion, show otherwise.
             for (span, assoc_items) in &associated_types {
-                let mut names: FxHashMap<_, usize> = FxHashMap::default();
+                let mut names: FxIndexMap<_, usize> = FxIndexMap::default();
                 for item in assoc_items {
                     types_count += 1;
                     *names.entry(item.name).or_insert(0) += 1;
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 98a27c5ed20..94c49453cdc 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -16,7 +16,7 @@ use crate::errors::AmbiguousLifetimeBound;
 use crate::middle::resolve_bound_vars as rbv;
 use crate::require_c_abi_if_c_variadic;
 use rustc_ast::TraitObjectSyntax;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::{
     codes::*, struct_span_code_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed,
     FatalError, MultiSpan,
@@ -752,7 +752,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
         debug!(?poly_trait_ref, ?assoc_bindings);
         bounds.push_trait_bound(tcx, poly_trait_ref, span, polarity);
 
-        let mut dup_bindings = FxHashMap::default();
+        let mut dup_bindings = FxIndexMap::default();
         for binding in &assoc_bindings {
             // Don't register additional associated type bounds for negative bounds,
             // since we should have emitten an error for them earlier, and they will
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index b693d7201c1..488d16f18da 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -1367,7 +1367,7 @@ fn check_type_alias_type_params_are_used<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalD
             // `Sized` bounds. If they came last for example, this would break `Trait + /*elab*/Sized`
             // since it would overwrite the span of the user-written bound. This could be fixed by
             // folding the spans with `Span::to` which requires a bit of effort I think.
-            .collect::<FxHashMap<_, _>>()
+            .collect::<FxIndexMap<_, _>>()
     });
 
     let mut params_used = BitSet::new_empty(generics.params.len());
diff --git a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
index 69a02b73a79..1dd27f0cc53 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -1,7 +1,7 @@
 use super::potentially_plural_count;
 use crate::errors::{LifetimesOrBoundsMismatchOnTrait, MethodShouldReturnFuture};
 use hir::def_id::{DefId, DefIdMap, LocalDefId};
-use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet};
 use rustc_errors::{codes::*, pluralize, struct_span_code_err, Applicability, ErrorGuaranteed};
 use rustc_hir as hir;
 use rustc_hir::def::{DefKind, Res};
@@ -392,7 +392,7 @@ fn compare_method_predicate_entailment<'tcx>(
 
 struct RemapLateBound<'a, 'tcx> {
     tcx: TyCtxt<'tcx>,
-    mapping: &'a FxHashMap<ty::BoundRegionKind, ty::BoundRegionKind>,
+    mapping: &'a FxIndexMap<ty::BoundRegionKind, ty::BoundRegionKind>,
 }
 
 impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateBound<'_, 'tcx> {
@@ -553,7 +553,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     // prove below that the hidden types are well formed.
     let universe = infcx.create_next_universe();
     let mut idx = 0;
-    let mapping: FxHashMap<_, _> = collector
+    let mapping: FxIndexMap<_, _> = collector
         .types
         .iter()
         .map(|(_, &(ty, _))| {
@@ -690,7 +690,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                 // contains `def_id`'s early-bound regions.
                 let id_args = GenericArgs::identity_for_item(tcx, def_id);
                 debug!(?id_args, ?args);
-                let map: FxHashMap<_, _> = std::iter::zip(args, id_args)
+                let map: FxIndexMap<_, _> = std::iter::zip(args, id_args)
                     .skip(tcx.generics_of(trait_m.def_id).count())
                     .filter_map(|(a, b)| Some((a.as_region()?, b.as_region()?)))
                     .collect();
@@ -766,7 +766,7 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
 
 struct ImplTraitInTraitCollector<'a, 'tcx> {
     ocx: &'a ObligationCtxt<'a, 'tcx>,
-    types: FxHashMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
+    types: FxIndexMap<DefId, (Ty<'tcx>, ty::GenericArgsRef<'tcx>)>,
     span: Span,
     param_env: ty::ParamEnv<'tcx>,
     body_id: LocalDefId,
@@ -779,7 +779,7 @@ impl<'a, 'tcx> ImplTraitInTraitCollector<'a, 'tcx> {
         param_env: ty::ParamEnv<'tcx>,
         body_id: LocalDefId,
     ) -> Self {
-        ImplTraitInTraitCollector { ocx, types: FxHashMap::default(), span, param_env, body_id }
+        ImplTraitInTraitCollector { ocx, types: FxIndexMap::default(), span, param_env, body_id }
     }
 }
 
@@ -838,7 +838,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for ImplTraitInTraitCollector<'_, 'tcx> {
 
 struct RemapHiddenTyRegions<'tcx> {
     tcx: TyCtxt<'tcx>,
-    map: FxHashMap<ty::Region<'tcx>, ty::Region<'tcx>>,
+    map: FxIndexMap<ty::Region<'tcx>, ty::Region<'tcx>>,
     num_trait_args: usize,
     num_impl_args: usize,
     def_id: DefId,
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 2f8e065df33..8884c218d05 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -76,7 +76,7 @@ pub use check::check_abi;
 
 use std::num::NonZeroU32;
 
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::ErrorGuaranteed;
 use rustc_errors::{pluralize, struct_span_code_err, Diagnostic, DiagnosticBuilder};
 use rustc_hir::def_id::{DefId, LocalDefId};
@@ -307,7 +307,7 @@ fn bounds_from_generic_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     predicates: impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>,
 ) -> (String, String) {
-    let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
+    let mut types: FxIndexMap<Ty<'tcx>, Vec<DefId>> = FxIndexMap::default();
     let mut projections = vec![];
     for (predicate, _) in predicates {
         debug!("predicate {:?}", predicate);
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index 951440d6a2d..9e1e884d976 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -1,4 +1,5 @@
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::IndexEntry;
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_errors::{codes::*, struct_span_code_err};
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
@@ -9,7 +10,6 @@ use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::{ErrorGuaranteed, Symbol};
 use rustc_trait_selection::traits::{self, SkipLeakCheck};
 use smallvec::SmallVec;
-use std::collections::hash_map::Entry;
 
 pub fn crate_inherent_impls_overlap_check(tcx: TyCtxt<'_>, (): ()) -> Result<(), ErrorGuaranteed> {
     let mut inherent_overlap_checker = InherentOverlapChecker { tcx };
@@ -63,7 +63,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
     fn check_for_duplicate_items_in_impl(&self, impl_: DefId) -> Result<(), ErrorGuaranteed> {
         let impl_items = self.tcx.associated_items(impl_);
 
-        let mut seen_items = FxHashMap::default();
+        let mut seen_items = FxIndexMap::default();
         let mut res = Ok(());
         for impl_item in impl_items.in_definition_order() {
             let span = self.tcx.def_span(impl_item.def_id);
@@ -71,7 +71,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
 
             let norm_ident = ident.normalize_to_macros_2_0();
             match seen_items.entry(norm_ident) {
-                Entry::Occupied(entry) => {
+                IndexEntry::Occupied(entry) => {
                     let former = entry.get();
                     res = Err(struct_span_code_err!(
                         self.tcx.dcx(),
@@ -84,7 +84,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
                     .with_span_label(*former, format!("other definition for `{ident}`"))
                     .emit());
                 }
-                Entry::Vacant(entry) => {
+                IndexEntry::Vacant(entry) => {
                     entry.insert(span);
                 }
             }
@@ -216,7 +216,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
             }
             let mut connected_regions: IndexVec<RegionId, _> = Default::default();
             // Reverse map from the Symbol to the connected region id.
-            let mut connected_region_ids = FxHashMap::default();
+            let mut connected_region_ids = FxIndexMap::default();
 
             for (i, &(&_impl_def_id, impl_items)) in impls_items.iter().enumerate() {
                 if impl_items.len() == 0 {
@@ -228,7 +228,7 @@ impl<'tcx> InherentOverlapChecker<'tcx> {
                     .in_definition_order()
                     .filter_map(|item| {
                         let entry = connected_region_ids.entry(item.name);
-                        if let Entry::Occupied(e) = &entry {
+                        if let IndexEntry::Occupied(e) = &entry {
                             Some(*e.get())
                         } else {
                             idents_to_add.push(item.name);
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 4891dae47c6..41420b9caec 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -15,7 +15,7 @@
 //! crate as a kind of pass. This should eventually be factored away.
 
 use rustc_data_structures::captures::Captures;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{Applicability, DiagnosticBuilder, ErrorGuaranteed, StashKey};
 use rustc_hir as hir;
@@ -834,12 +834,12 @@ impl From<NestedSpan> for FieldDeclSpan {
 
 struct FieldUniquenessCheckContext<'tcx> {
     tcx: TyCtxt<'tcx>,
-    seen_fields: FxHashMap<Ident, FieldDeclSpan>,
+    seen_fields: FxIndexMap<Ident, FieldDeclSpan>,
 }
 
 impl<'tcx> FieldUniquenessCheckContext<'tcx> {
     fn new(tcx: TyCtxt<'tcx>) -> Self {
-        Self { tcx, seen_fields: FxHashMap::default() }
+        Self { tcx, seen_fields: FxIndexMap::default() }
     }
 
     /// Check if a given field `ident` declared at `field_decl` has been declared elsewhere before.
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 1cd77050217..33092825e89 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -178,8 +178,9 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
             let _ = tcx.ensure().coherent_trait(trait_def_id);
         }
         // these queries are executed for side-effects (error reporting):
-        res.and(tcx.ensure().crate_inherent_impls(()))
-            .and(tcx.ensure().crate_inherent_impls_overlap_check(()))
+        let _ = tcx.ensure().crate_inherent_impls(());
+        let _ = tcx.ensure().crate_inherent_impls_overlap_check(());
+        res
     })?;
 
     if tcx.features().rustc_attrs {
diff --git a/compiler/rustc_hir_analysis/src/outlives/explicit.rs b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
index a7fca41f86a..1de7a0f7bc7 100644
--- a/compiler/rustc_hir_analysis/src/outlives/explicit.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/explicit.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, OutlivesPredicate, TyCtxt};
 
@@ -6,12 +6,12 @@ use super::utils::*;
 
 #[derive(Debug)]
 pub struct ExplicitPredicatesMap<'tcx> {
-    map: FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    map: FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
 }
 
 impl<'tcx> ExplicitPredicatesMap<'tcx> {
     pub fn new() -> ExplicitPredicatesMap<'tcx> {
-        ExplicitPredicatesMap { map: FxHashMap::default() }
+        ExplicitPredicatesMap { map: FxIndexMap::default() }
     }
 
     pub(crate) fn explicit_predicates_of(
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index 0c0dbbe7ad9..e6c582667ba 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -1,4 +1,4 @@
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -15,12 +15,12 @@ use super::utils::*;
 ///     now be filled with inferred predicates.
 pub(super) fn infer_predicates(
     tcx: TyCtxt<'_>,
-) -> FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'_>>> {
+) -> FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'_>>> {
     debug!("infer_predicates");
 
     let mut explicit_map = ExplicitPredicatesMap::new();
 
-    let mut global_inferred_outlives = FxHashMap::default();
+    let mut global_inferred_outlives = FxIndexMap::default();
 
     // If new predicates were added then we need to re-calculate
     // all crates since there could be new implied predicates.
@@ -101,7 +101,7 @@ fn insert_required_predicates_to_be_wf<'tcx>(
     tcx: TyCtxt<'tcx>,
     ty: Ty<'tcx>,
     span: Span,
-    global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
     required_predicates: &mut RequiredPredicates<'tcx>,
     explicit_map: &mut ExplicitPredicatesMap<'tcx>,
 ) {
@@ -322,7 +322,7 @@ fn check_inferred_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
     def_id: DefId,
     args: ty::GenericArgsRef<'tcx>,
-    global_inferred_outlives: &FxHashMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
+    global_inferred_outlives: &FxIndexMap<DefId, ty::EarlyBinder<RequiredPredicates<'tcx>>>,
     required_predicates: &mut RequiredPredicates<'tcx>,
 ) {
     // Load the current set of inferred and explicit predicates from `global_inferred_outlives`
diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs
index 19bdeab409b..949fbb65dbd 100644
--- a/compiler/rustc_hir_typeck/src/expr.rs
+++ b/compiler/rustc_hir_typeck/src/expr.rs
@@ -24,6 +24,7 @@ use crate::{
 use rustc_ast as ast;
 use rustc_data_structures::fx::{FxHashMap, FxHashSet};
 use rustc_data_structures::stack::ensure_sufficient_stack;
+use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{
     codes::*, pluralize, struct_span_code_err, AddToDiagnostic, Applicability, Diagnostic,
     DiagnosticBuilder, ErrCode, ErrorGuaranteed, StashKey,
@@ -1709,7 +1710,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
             .fields
             .iter_enumerated()
             .map(|(i, field)| (field.ident(tcx).normalize_to_macros_2_0(), (i, field)))
-            .collect::<FxHashMap<_, _>>();
+            .collect::<UnordMap<_, _>>();
 
         let mut seen_fields = FxHashMap::default();
 
@@ -1954,18 +1955,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         adt_ty: Ty<'tcx>,
         span: Span,
-        remaining_fields: FxHashMap<Ident, (FieldIdx, &ty::FieldDef)>,
+        remaining_fields: UnordMap<Ident, (FieldIdx, &ty::FieldDef)>,
         variant: &'tcx ty::VariantDef,
         ast_fields: &'tcx [hir::ExprField<'tcx>],
         args: GenericArgsRef<'tcx>,
     ) {
         let len = remaining_fields.len();
 
-        #[allow(rustc::potential_query_instability)]
-        let mut displayable_field_names: Vec<&str> =
-            remaining_fields.keys().map(|ident| ident.as_str()).collect();
-        // sorting &str primitives here, sort_unstable is ok
-        displayable_field_names.sort_unstable();
+        let displayable_field_names: Vec<&str> =
+            remaining_fields.items().map(|(ident, _)| ident.as_str()).into_sorted_stable_ord();
 
         let mut truncated_fields_error = String::new();
         let remaining_fields_names = match &displayable_field_names[..] {
diff --git a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
index 65b8505c090..3bce8a1dd45 100644
--- a/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
+++ b/compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs
@@ -1319,7 +1319,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
                 tcx.type_of(tcx.require_lang_item(hir::LangItem::CStr, Some(lit.span)))
                     .skip_binder(),
             ),
-            ast::LitKind::Err => Ty::new_misc_error(tcx),
+            ast::LitKind::Err(guar) => Ty::new_error(tcx, guar),
         }
     }
 
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 50b2bf7da15..60d13f02ad7 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -306,11 +306,7 @@ fn early_lint_checks(tcx: TyCtxt<'_>, (): ()) {
 
     // Gate identifiers containing invalid Unicode codepoints that were recovered during lexing.
     sess.parse_sess.bad_unicode_identifiers.with_lock(|identifiers| {
-        // We will soon sort, so the initial order does not matter.
-        #[allow(rustc::potential_query_instability)]
-        let mut identifiers: Vec<_> = identifiers.drain().collect();
-        identifiers.sort_by_key(|&(key, _)| key);
-        for (ident, mut spans) in identifiers.into_iter() {
+        for (ident, mut spans) in identifiers.drain(..) {
             spans.sort();
             if ident == sym::ferris {
                 let first_span = spans[0];
diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs
index 30f05444d21..5e27a0ed818 100644
--- a/compiler/rustc_lint/src/context.rs
+++ b/compiler/rustc_lint/src/context.rs
@@ -18,8 +18,9 @@ use self::TargetLint::*;
 
 use crate::levels::LintLevelsBuilder;
 use crate::passes::{EarlyLintPassObject, LateLintPassObject};
-use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::sync;
+use rustc_data_structures::unord::UnordMap;
 use rustc_errors::{DecorateLint, DiagnosticBuilder, DiagnosticMessage, MultiSpan};
 use rustc_feature::Features;
 use rustc_hir as hir;
@@ -69,10 +70,10 @@ pub struct LintStore {
     pub late_module_passes: Vec<Box<LateLintPassFactory>>,
 
     /// Lints indexed by name.
-    by_name: FxHashMap<String, TargetLint>,
+    by_name: UnordMap<String, TargetLint>,
 
     /// Map of registered lint groups to what lints they expand to.
-    lint_groups: FxHashMap<&'static str, LintGroup>,
+    lint_groups: FxIndexMap<&'static str, LintGroup>,
 }
 
 impl LintStoreMarker for LintStore {}
@@ -152,8 +153,6 @@ impl LintStore {
     pub fn get_lint_groups<'t>(
         &'t self,
     ) -> impl Iterator<Item = (&'static str, Vec<LintId>, bool)> + 't {
-        // This function is not used in a way which observes the order of lints.
-        #[allow(rustc::potential_query_instability)]
         self.lint_groups
             .iter()
             .filter(|(_, LintGroup { depr, .. })| {
@@ -326,9 +325,11 @@ impl LintStore {
 
     /// True if this symbol represents a lint group name.
     pub fn is_lint_group(&self, lint_name: Symbol) -> bool {
-        #[allow(rustc::potential_query_instability)]
-        let lint_groups = self.lint_groups.keys().collect::<Vec<_>>();
-        debug!("is_lint_group(lint_name={:?}, lint_groups={:?})", lint_name, lint_groups);
+        debug!(
+            "is_lint_group(lint_name={:?}, lint_groups={:?})",
+            lint_name,
+            self.lint_groups.keys().collect::<Vec<_>>()
+        );
         let lint_name_str = lint_name.as_str();
         self.lint_groups.contains_key(lint_name_str) || {
             let warnings_name_str = crate::WARNINGS.name_lower();
@@ -372,12 +373,9 @@ impl LintStore {
                     None => {
                         // 1. The tool is currently running, so this lint really doesn't exist.
                         // FIXME: should this handle tools that never register a lint, like rustfmt?
-                        #[allow(rustc::potential_query_instability)]
-                        let lints = self.by_name.keys().collect::<Vec<_>>();
-                        debug!("lints={:?}", lints);
+                        debug!("lints={:?}", self.by_name);
                         let tool_prefix = format!("{tool_name}::");
 
-                        #[allow(rustc::potential_query_instability)]
                         return if self.by_name.keys().any(|lint| lint.starts_with(&tool_prefix)) {
                             self.no_lint_suggestion(&complete_name, tool_name.as_str())
                         } else {
diff --git a/compiler/rustc_lint/src/non_ascii_idents.rs b/compiler/rustc_lint/src/non_ascii_idents.rs
index f78b32ce5e7..e112cd6915c 100644
--- a/compiler/rustc_lint/src/non_ascii_idents.rs
+++ b/compiler/rustc_lint/src/non_ascii_idents.rs
@@ -179,7 +179,6 @@ impl EarlyLintPass for NonAsciiIdents {
         #[allow(rustc::potential_query_instability)]
         let mut symbols: Vec<_> = symbols.iter().collect();
         symbols.sort_by_key(|k| k.1);
-
         for (symbol, &sp) in symbols.iter() {
             let symbol_str = symbol.as_str();
             if symbol_str.is_ascii() {
diff --git a/compiler/rustc_lint/src/reference_casting.rs b/compiler/rustc_lint/src/reference_casting.rs
index 519ab8bd50f..f386db9d8db 100644
--- a/compiler/rustc_lint/src/reference_casting.rs
+++ b/compiler/rustc_lint/src/reference_casting.rs
@@ -207,6 +207,13 @@ fn is_cast_to_bigger_memory_layout<'tcx>(
     }
 
     let from_layout = cx.layout_of(*inner_start_ty).ok()?;
+
+    // if the type isn't sized, we bail out, instead of potentially giving
+    // the user a meaningless warning.
+    if from_layout.is_unsized() {
+        return None;
+    }
+
     let alloc_layout = cx.layout_of(alloc_ty).ok()?;
     let to_layout = cx.layout_of(*inner_end_ty).ok()?;
 
diff --git a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
index d79d4b226a5..178bfc3a380 100644
--- a/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
+++ b/compiler/rustc_metadata/src/rmeta/decoder/cstore_impl.rs
@@ -250,6 +250,15 @@ provide! { tcx, def_id, other, cdata,
     fn_arg_names => { table }
     coroutine_kind => { table_direct }
     coroutine_for_closure => { table }
+    eval_static_initializer => {
+        Ok(cdata
+            .root
+            .tables
+            .eval_static_initializer
+            .get(cdata, def_id.index)
+            .map(|lazy| lazy.decode((cdata, tcx)))
+            .unwrap_or_else(|| panic!("{def_id:?} does not have eval_static_initializer")))
+    }
     trait_def => { table }
     deduced_param_attrs => { table }
     is_type_alias_impl_trait => {
diff --git a/compiler/rustc_metadata/src/rmeta/encoder.rs b/compiler/rustc_metadata/src/rmeta/encoder.rs
index 4a24c038f7a..6f908f7752a 100644
--- a/compiler/rustc_metadata/src/rmeta/encoder.rs
+++ b/compiler/rustc_metadata/src/rmeta/encoder.rs
@@ -1045,11 +1045,9 @@ fn should_encode_mir(
             (true, mir_opt_base)
         }
         // Constants
-        DefKind::AnonConst
-        | DefKind::InlineConst
-        | DefKind::AssocConst
-        | DefKind::Static(..)
-        | DefKind::Const => (true, false),
+        DefKind::AnonConst | DefKind::InlineConst | DefKind::AssocConst | DefKind::Const => {
+            (true, false)
+        }
         // Coroutines require optimized MIR to compute layout.
         DefKind::Closure if tcx.is_coroutine(def_id.to_def_id()) => (false, true),
         // Full-fledged functions + closures
@@ -1454,6 +1452,12 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     .coroutine_for_closure
                     .set_some(def_id.index, self.tcx.coroutine_for_closure(def_id).into());
             }
+            if let DefKind::Static(_) = def_kind {
+                if !self.tcx.is_foreign_item(def_id) {
+                    let data = self.tcx.eval_static_initializer(def_id).unwrap();
+                    record!(self.tables.eval_static_initializer[def_id] <- data);
+                }
+            }
             if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
                 self.encode_info_for_adt(local_id);
             }
diff --git a/compiler/rustc_metadata/src/rmeta/mod.rs b/compiler/rustc_metadata/src/rmeta/mod.rs
index 4d0a6cb60ee..eac78a3cd7c 100644
--- a/compiler/rustc_metadata/src/rmeta/mod.rs
+++ b/compiler/rustc_metadata/src/rmeta/mod.rs
@@ -443,6 +443,7 @@ define_tables! {
     fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
     coroutine_kind: Table<DefIndex, hir::CoroutineKind>,
     coroutine_for_closure: Table<DefIndex, RawDefId>,
+    eval_static_initializer: Table<DefIndex, LazyValue<mir::interpret::ConstAllocation<'static>>>,
     trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
     trait_item_def_id: Table<DefIndex, RawDefId>,
     expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,
diff --git a/compiler/rustc_middle/src/mir/interpret/error.rs b/compiler/rustc_middle/src/mir/interpret/error.rs
index a1cdc794749..9d4ec7d25bb 100644
--- a/compiler/rustc_middle/src/mir/interpret/error.rs
+++ b/compiler/rustc_middle/src/mir/interpret/error.rs
@@ -1,4 +1,4 @@
-use super::{AllocId, AllocRange, Pointer, Scalar};
+use super::{AllocId, AllocRange, ConstAllocation, Pointer, Scalar};
 
 use crate::error;
 use crate::mir::{ConstAlloc, ConstValue};
@@ -83,6 +83,7 @@ impl Into<ErrorGuaranteed> for ReportedErrorInfo {
 TrivialTypeTraversalImpls! { ErrorHandled }
 
 pub type EvalToAllocationRawResult<'tcx> = Result<ConstAlloc<'tcx>, ErrorHandled>;
+pub type EvalStaticInitializerRawResult<'tcx> = Result<ConstAllocation<'tcx>, ErrorHandled>;
 pub type EvalToConstValueResult<'tcx> = Result<ConstValue<'tcx>, ErrorHandled>;
 /// `Ok(None)` indicates the constant was fine, but the valtree couldn't be constructed.
 /// This is needed in `thir::pattern::lower_inline_const`.
diff --git a/compiler/rustc_middle/src/mir/interpret/mod.rs b/compiler/rustc_middle/src/mir/interpret/mod.rs
index 0da3524e055..ec2af393639 100644
--- a/compiler/rustc_middle/src/mir/interpret/mod.rs
+++ b/compiler/rustc_middle/src/mir/interpret/mod.rs
@@ -142,11 +142,12 @@ use crate::ty::GenericArgKind;
 use crate::ty::{self, Instance, Ty, TyCtxt};
 
 pub use self::error::{
-    BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalToAllocationRawResult,
-    EvalToConstValueResult, EvalToValTreeResult, ExpectedKind, InterpError, InterpErrorInfo,
-    InterpResult, InvalidMetaKind, InvalidProgramInfo, MachineStopType, Misalignment, PointerKind,
-    ReportedErrorInfo, ResourceExhaustionInfo, ScalarSizeMismatch, UndefinedBehaviorInfo,
-    UnsupportedOpInfo, ValidationErrorInfo, ValidationErrorKind,
+    BadBytesAccess, CheckAlignMsg, CheckInAllocMsg, ErrorHandled, EvalStaticInitializerRawResult,
+    EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult, ExpectedKind,
+    InterpError, InterpErrorInfo, InterpResult, InvalidMetaKind, InvalidProgramInfo,
+    MachineStopType, Misalignment, PointerKind, ReportedErrorInfo, ResourceExhaustionInfo,
+    ScalarSizeMismatch, UndefinedBehaviorInfo, UnsupportedOpInfo, ValidationErrorInfo,
+    ValidationErrorKind,
 };
 
 pub use self::value::Scalar;
diff --git a/compiler/rustc_middle/src/mir/interpret/queries.rs b/compiler/rustc_middle/src/mir/interpret/queries.rs
index e8aca5f2e7d..643b61c1de3 100644
--- a/compiler/rustc_middle/src/mir/interpret/queries.rs
+++ b/compiler/rustc_middle/src/mir/interpret/queries.rs
@@ -1,7 +1,7 @@
 use super::{ErrorHandled, EvalToConstValueResult, EvalToValTreeResult, GlobalId};
 
 use crate::mir;
-use crate::query::{TyCtxtAt, TyCtxtEnsure};
+use crate::query::TyCtxtEnsure;
 use crate::ty::visit::TypeVisitableExt;
 use crate::ty::GenericArgs;
 use crate::ty::{self, TyCtxt};
@@ -173,44 +173,6 @@ impl<'tcx> TyCtxt<'tcx> {
             self.eval_to_valtree(inputs)
         }
     }
-
-    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
-    #[inline(always)]
-    pub fn eval_static_initializer(
-        self,
-        def_id: DefId,
-    ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
-        self.at(DUMMY_SP).eval_static_initializer(def_id)
-    }
-}
-
-impl<'tcx> TyCtxtAt<'tcx> {
-    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
-    ///
-    /// The span is entirely ignored here, but still helpful for better query cycle errors.
-    pub fn eval_static_initializer(
-        self,
-        def_id: DefId,
-    ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
-        trace!("eval_static_initializer: Need to compute {:?}", def_id);
-        assert!(self.is_static(def_id));
-        let instance = ty::Instance::mono(*self, def_id);
-        let gid = GlobalId { instance, promoted: None };
-        self.eval_to_allocation(gid, ty::ParamEnv::reveal_all())
-    }
-
-    /// Evaluate anything constant-like, returning the allocation of the final memory.
-    ///
-    /// The span is entirely ignored here, but still helpful for better query cycle errors.
-    fn eval_to_allocation(
-        self,
-        gid: GlobalId<'tcx>,
-        param_env: ty::ParamEnv<'tcx>,
-    ) -> Result<mir::ConstAllocation<'tcx>, ErrorHandled> {
-        trace!("eval_to_allocation: Need to compute {:?}", gid);
-        let raw_const = self.eval_to_allocation_raw(param_env.and(gid))?;
-        Ok(self.global_alloc(raw_const.alloc_id).unwrap_memory())
-    }
 }
 
 impl<'tcx> TyCtxtEnsure<'tcx> {
@@ -232,15 +194,4 @@ impl<'tcx> TyCtxtEnsure<'tcx> {
         let inputs = self.tcx.erase_regions(param_env.and(cid));
         self.eval_to_const_value_raw(inputs)
     }
-
-    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
-    pub fn eval_static_initializer(self, def_id: DefId) {
-        trace!("eval_static_initializer: Need to compute {:?}", def_id);
-        assert!(self.tcx.is_static(def_id));
-        let instance = ty::Instance::mono(self.tcx, def_id);
-        let gid = GlobalId { instance, promoted: None };
-        let param_env = ty::ParamEnv::reveal_all();
-        trace!("eval_to_allocation: Need to compute {:?}", gid);
-        self.eval_to_allocation_raw(param_env.and(gid))
-    }
 }
diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs
index e22d5228628..3017f912ef0 100644
--- a/compiler/rustc_middle/src/mir/mod.rs
+++ b/compiler/rustc_middle/src/mir/mod.rs
@@ -2,7 +2,7 @@
 //!
 //! [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/mir/index.html
 
-use crate::mir::interpret::{AllocRange, ConstAllocation, Scalar};
+use crate::mir::interpret::{AllocRange, Scalar};
 use crate::mir::visit::MirVisitable;
 use crate::ty::codec::{TyDecoder, TyEncoder};
 use crate::ty::fold::{FallibleTypeFolder, TypeFoldable};
diff --git a/compiler/rustc_middle/src/mir/mono.rs b/compiler/rustc_middle/src/mir/mono.rs
index 3cd251caf5e..43e1318a75a 100644
--- a/compiler/rustc_middle/src/mir/mono.rs
+++ b/compiler/rustc_middle/src/mir/mono.rs
@@ -4,6 +4,7 @@ use rustc_attr::InlineAttr;
 use rustc_data_structures::base_n;
 use rustc_data_structures::fingerprint::Fingerprint;
 use rustc_data_structures::fx::FxHashMap;
+use rustc_data_structures::fx::FxIndexMap;
 use rustc_data_structures::stable_hasher::{Hash128, HashStable, StableHasher};
 use rustc_hir::def_id::{CrateNum, DefId, LOCAL_CRATE};
 use rustc_hir::ItemId;
@@ -241,7 +242,7 @@ pub struct CodegenUnit<'tcx> {
     /// contain something unique to this crate (e.g., a module path)
     /// as well as the crate name and disambiguator.
     name: Symbol,
-    items: FxHashMap<MonoItem<'tcx>, MonoItemData>,
+    items: FxIndexMap<MonoItem<'tcx>, MonoItemData>,
     size_estimate: usize,
     primary: bool,
     /// True if this is CGU is used to hold code coverage information for dead code,
@@ -316,13 +317,11 @@ impl<'tcx> CodegenUnit<'tcx> {
         self.primary = true;
     }
 
-    /// The order of these items is non-determinstic.
-    pub fn items(&self) -> &FxHashMap<MonoItem<'tcx>, MonoItemData> {
+    pub fn items(&self) -> &FxIndexMap<MonoItem<'tcx>, MonoItemData> {
         &self.items
     }
 
-    /// The order of these items is non-determinstic.
-    pub fn items_mut(&mut self) -> &mut FxHashMap<MonoItem<'tcx>, MonoItemData> {
+    pub fn items_mut(&mut self) -> &mut FxIndexMap<MonoItem<'tcx>, MonoItemData> {
         &mut self.items
     }
 
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a011f6114de..5638b575b31 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -4,6 +4,8 @@ use std::fs;
 use std::io::{self, Write as _};
 use std::path::{Path, PathBuf};
 
+use crate::mir::interpret::ConstAllocation;
+
 use super::graphviz::write_mir_fn_graphviz;
 use rustc_ast::InlineAsmTemplatePiece;
 use rustc_middle::mir::interpret::{
diff --git a/compiler/rustc_middle/src/query/erase.rs b/compiler/rustc_middle/src/query/erase.rs
index 5666a59e38e..7ac7fa0ac33 100644
--- a/compiler/rustc_middle/src/query/erase.rs
+++ b/compiler/rustc_middle/src/query/erase.rs
@@ -337,6 +337,7 @@ tcx_lifetime! {
     rustc_middle::mir::ConstValue,
     rustc_middle::mir::interpret::GlobalId,
     rustc_middle::mir::interpret::LitToConstInput,
+    rustc_middle::mir::interpret::EvalStaticInitializerRawResult,
     rustc_middle::traits::query::MethodAutoderefStepsResult,
     rustc_middle::traits::query::type_op::AscribeUserType,
     rustc_middle::traits::query::type_op::Eq,
diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs
index 60d195e4d3e..a7f4e75e214 100644
--- a/compiler/rustc_middle/src/query/mod.rs
+++ b/compiler/rustc_middle/src/query/mod.rs
@@ -20,7 +20,8 @@ use crate::middle::stability::{self, DeprecationEntry};
 use crate::mir;
 use crate::mir::interpret::GlobalId;
 use crate::mir::interpret::{
-    EvalToAllocationRawResult, EvalToConstValueResult, EvalToValTreeResult,
+    EvalStaticInitializerRawResult, EvalToAllocationRawResult, EvalToConstValueResult,
+    EvalToValTreeResult,
 };
 use crate::mir::interpret::{LitToConstError, LitToConstInput};
 use crate::mir::mono::CodegenUnit;
@@ -1061,7 +1062,7 @@ rustc_queries! {
 
     /// Evaluates a constant and returns the computed allocation.
     ///
-    /// **Do not use this** directly, use the `tcx.eval_static_initializer` wrapper.
+    /// **Do not use this** directly, use the `eval_to_const_value` or `eval_to_valtree` instead.
     query eval_to_allocation_raw(key: ty::ParamEnvAnd<'tcx, GlobalId<'tcx>>)
         -> EvalToAllocationRawResult<'tcx> {
         desc { |tcx|
@@ -1071,6 +1072,16 @@ rustc_queries! {
         cache_on_disk_if { true }
     }
 
+    /// Evaluate a static's initializer, returning the allocation of the initializer's memory.
+    query eval_static_initializer(key: DefId) -> EvalStaticInitializerRawResult<'tcx> {
+        desc { |tcx|
+            "evaluating initializer of static `{}`",
+            tcx.def_path_str(key)
+        }
+        cache_on_disk_if { key.is_local() }
+        separate_provide_extern
+    }
+
     /// Evaluates const items or anonymous constants
     /// (such as enum variant explicit discriminants or array lengths)
     /// into a representation suitable for the type system and const generics.
diff --git a/compiler/rustc_middle/src/ty/parameterized.rs b/compiler/rustc_middle/src/ty/parameterized.rs
index 045856dd9cd..22f0574d614 100644
--- a/compiler/rustc_middle/src/ty/parameterized.rs
+++ b/compiler/rustc_middle/src/ty/parameterized.rs
@@ -126,6 +126,7 @@ parameterized_over_tcx! {
     crate::middle::exported_symbols::ExportedSymbol,
     crate::mir::Body,
     crate::mir::CoroutineLayout,
+    crate::mir::interpret::ConstAllocation,
     ty::Ty,
     ty::FnSig,
     ty::GenericPredicates,
diff --git a/compiler/rustc_middle/src/ty/sty.rs b/compiler/rustc_middle/src/ty/sty.rs
index 66086ac87f1..a5817125267 100644
--- a/compiler/rustc_middle/src/ty/sty.rs
+++ b/compiler/rustc_middle/src/ty/sty.rs
@@ -2363,28 +2363,42 @@ impl<'tcx> Ty<'tcx> {
     }
 
     /// When we create a closure, we record its kind (i.e., what trait
-    /// it implements) into its `ClosureArgs` using a type
+    /// it implements, constrained by how it uses its borrows) into its
+    /// [`ty::ClosureArgs`] or [`ty::CoroutineClosureArgs`] using a type
     /// parameter. This is kind of a phantom type, except that the
     /// most convenient thing for us to are the integral types. This
     /// function converts such a special type into the closure
-    /// kind. To go the other way, use `closure_kind.to_ty(tcx)`.
+    /// kind. To go the other way, use [`Ty::from_closure_kind`].
     ///
     /// Note that during type checking, we use an inference variable
     /// to represent the closure kind, because it has not yet been
     /// inferred. Once upvar inference (in `rustc_hir_analysis/src/check/upvar.rs`)
-    /// is complete, that type variable will be unified.
+    /// is complete, that type variable will be unified with one of
+    /// the integral types.
     ///
-    /// To be noted that you can use [`ClosureArgs::kind()`] or [`CoroutineClosureArgs::kind()`]
-    /// to get the same information, which you can get by calling [`GenericArgs::as_closure()`]
-    /// or [`GenericArgs::as_coroutine_closure()`], depending on the type of the closure.
+    /// ```rust,ignore (snippet of compiler code)
+    /// if let TyKind::Closure(def_id, args) = closure_ty.kind()
+    ///     && let Some(closure_kind) = args.as_closure().kind_ty().to_opt_closure_kind()
+    /// {
+    ///     println!("{closure_kind:?}");
+    /// } else if let TyKind::CoroutineClosure(def_id, args) = closure_ty.kind()
+    ///     && let Some(closure_kind) = args.as_coroutine_closure().kind_ty().to_opt_closure_kind()
+    /// {
+    ///     println!("{closure_kind:?}");
+    /// }
+    /// ```
     ///
-    /// Otherwise, this method can be used as follows:
+    /// After upvar analysis, you should instead use [`ClosureArgs::kind()`]
+    /// or [`CoroutineClosureArgs::kind()`] to assert that the `ClosureKind`
+    /// has been constrained instead of manually calling this method.
     ///
     /// ```rust,ignore (snippet of compiler code)
-    /// let TyKind::Closure(def_id, [closure_fn_kind_ty, ..]) = closure_ty.kind()
-    ///     && let Some(closure_kind) = closure_fn_kind_ty.expect_ty().to_opt_closure_kind()
+    /// if let TyKind::Closure(def_id, args) = closure_ty.kind()
+    /// {
+    ///     println!("{:?}", args.as_closure().kind());
+    /// } else if let TyKind::CoroutineClosure(def_id, args) = closure_ty.kind()
     /// {
-    ///     // your code
+    ///     println!("{:?}", args.as_coroutine_closure().kind());
     /// }
     /// ```
     pub fn to_opt_closure_kind(self) -> Option<ty::ClosureKind> {
@@ -2406,7 +2420,8 @@ impl<'tcx> Ty<'tcx> {
         }
     }
 
-    /// Inverse of [`Ty::to_opt_closure_kind`].
+    /// Inverse of [`Ty::to_opt_closure_kind`]. See docs on that method
+    /// for explanation of the relationship between `Ty` and [`ty::ClosureKind`].
     pub fn from_closure_kind(tcx: TyCtxt<'tcx>, kind: ty::ClosureKind) -> Ty<'tcx> {
         match kind {
             ty::ClosureKind::Fn => tcx.types.i8,
diff --git a/compiler/rustc_mir_build/src/build/expr/as_constant.rs b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
index 6636f75d998..7c3d2671d59 100644
--- a/compiler/rustc_mir_build/src/build/expr/as_constant.rs
+++ b/compiler/rustc_mir_build/src/build/expr/as_constant.rs
@@ -164,11 +164,7 @@ fn lit_to_mir_constant<'tcx>(
             })?,
         (ast::LitKind::Bool(b), ty::Bool) => ConstValue::Scalar(Scalar::from_bool(*b)),
         (ast::LitKind::Char(c), ty::Char) => ConstValue::Scalar(Scalar::from_char(*c)),
-        (ast::LitKind::Err, _) => {
-            return Err(LitToConstError::Reported(
-                tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
-            ));
-        }
+        (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs
index 71aebd13003..d444de8b28e 100644
--- a/compiler/rustc_mir_build/src/thir/constant.rs
+++ b/compiler/rustc_mir_build/src/thir/constant.rs
@@ -71,11 +71,7 @@ pub(crate) fn lit_to_const<'tcx>(
             ty::ValTree::from_scalar_int(bits)
         }
         (ast::LitKind::Char(c), ty::Char) => ty::ValTree::from_scalar_int((*c).into()),
-        (ast::LitKind::Err, _) => {
-            return Err(LitToConstError::Reported(
-                tcx.dcx().delayed_bug("encountered LitKind::Err during mir build"),
-            ));
-        }
+        (ast::LitKind::Err(guar), _) => return Err(LitToConstError::Reported(*guar)),
         _ => return Err(LitToConstError::TypeError),
     };
 
diff --git a/compiler/rustc_mir_build/src/thir/cx/expr.rs b/compiler/rustc_mir_build/src/thir/cx/expr.rs
index 99952e1c178..62762168cf4 100644
--- a/compiler/rustc_mir_build/src/thir/cx/expr.rs
+++ b/compiler/rustc_mir_build/src/thir/cx/expr.rs
@@ -897,12 +897,14 @@ impl<'tcx> Cx<'tcx> {
                 let hir_id = self.tcx.local_def_id_to_hir_id(def_id.expect_local());
                 let generics = self.tcx.generics_of(hir_id.owner);
                 let Some(&index) = generics.param_def_id_to_index.get(&def_id) else {
-                    self.tcx.dcx().has_errors().unwrap();
+                    let guar = self.tcx.dcx().has_errors().unwrap();
                     // We already errored about a late bound const
-                    return ExprKind::Literal {
-                        lit: &Spanned { span: DUMMY_SP, node: LitKind::Err },
-                        neg: false,
-                    };
+
+                    let lit = self
+                        .tcx
+                        .hir_arena
+                        .alloc(Spanned { span: DUMMY_SP, node: LitKind::Err(guar) });
+                    return ExprKind::Literal { lit, neg: false };
                 };
                 let name = self.tcx.hir().name(hir_id);
                 let param = ty::ParamConst::new(index, name);
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 370f0db72cb..a080e2423d4 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -399,7 +399,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                     };
                     for (field_index, op) in fields.into_iter().enumerate() {
                         let field_dest = self.ecx.project_field(&variant_dest, field_index).ok()?;
-                        self.ecx.copy_op(op, &field_dest, /*allow_transmute*/ false).ok()?;
+                        self.ecx.copy_op(op, &field_dest).ok()?;
                     }
                     self.ecx.write_discriminant(variant.unwrap_or(FIRST_VARIANT), &dest).ok()?;
                     self.ecx
@@ -1181,8 +1181,7 @@ fn op_to_prop_const<'tcx>(
     }
 
     // Everything failed: create a new allocation to hold the data.
-    let alloc_id =
-        ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest, false)).ok()?;
+    let alloc_id = ecx.intern_with_temp_alloc(op.layout, |ecx, dest| ecx.copy_op(op, dest)).ok()?;
     let value = ConstValue::Indirect { alloc_id, offset: Size::ZERO };
 
     // Check that we do not leak a pointer.
diff --git a/compiler/rustc_mir_transform/src/jump_threading.rs b/compiler/rustc_mir_transform/src/jump_threading.rs
index 78ba166ba43..ad8f21ffbda 100644
--- a/compiler/rustc_mir_transform/src/jump_threading.rs
+++ b/compiler/rustc_mir_transform/src/jump_threading.rs
@@ -68,6 +68,12 @@ impl<'tcx> MirPass<'tcx> for JumpThreading {
         let def_id = body.source.def_id();
         debug!(?def_id);
 
+        // Optimizing coroutines creates query cycles.
+        if tcx.is_coroutine(def_id) {
+            trace!("Skipped for coroutine {:?}", def_id);
+            return;
+        }
+
         let param_env = tcx.param_env_reveal_all_normalized(def_id);
         let map = Map::new(tcx, body, Some(MAX_PLACES));
         let loop_headers = loop_headers(body);
diff --git a/compiler/rustc_monomorphize/src/partitioning.rs b/compiler/rustc_monomorphize/src/partitioning.rs
index 5cfebcaa5a5..8bebc30e435 100644
--- a/compiler/rustc_monomorphize/src/partitioning.rs
+++ b/compiler/rustc_monomorphize/src/partitioning.rs
@@ -368,7 +368,7 @@ fn merge_codegen_units<'tcx>(
         // Move the items from `cgu_src` to `cgu_dst`. Some of them may be
         // duplicate inlined items, in which case the destination CGU is
         // unaffected. Recalculate size estimates afterwards.
-        cgu_dst.items_mut().extend(cgu_src.items_mut().drain());
+        cgu_dst.items_mut().extend(cgu_src.items_mut().drain(..));
         cgu_dst.compute_size_estimate();
 
         // Record that `cgu_dst` now contains all the stuff that was in
@@ -407,7 +407,7 @@ fn merge_codegen_units<'tcx>(
         // Move the items from `smallest` to `second_smallest`. Some of them
         // may be duplicate inlined items, in which case the destination CGU is
         // unaffected. Recalculate size estimates afterwards.
-        second_smallest.items_mut().extend(smallest.items_mut().drain());
+        second_smallest.items_mut().extend(smallest.items_mut().drain(..));
         second_smallest.compute_size_estimate();
 
         // Don't update `cgu_contents`, that's only for incremental builds.
diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs
index 31552452676..c768ea93b5f 100644
--- a/compiler/rustc_parse/src/lexer/mod.rs
+++ b/compiler/rustc_parse/src/lexer/mod.rs
@@ -16,7 +16,7 @@ use rustc_session::lint::builtin::{
 };
 use rustc_session::lint::BuiltinLintDiagnostics;
 use rustc_session::parse::ParseSess;
-use rustc_span::symbol::{sym, Symbol};
+use rustc_span::symbol::Symbol;
 use rustc_span::{edition::Edition, BytePos, Pos, Span};
 
 mod diagnostics;
@@ -478,26 +478,27 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 }
             }
             rustc_lexer::LiteralKind::Int { base, empty_int } => {
+                let mut kind = token::Integer;
                 if empty_int {
                     let span = self.mk_sp(start, end);
-                    self.dcx().emit_err(errors::NoDigitsLiteral { span });
-                    (token::Integer, sym::integer(0))
-                } else {
-                    if matches!(base, Base::Binary | Base::Octal) {
-                        let base = base as u32;
-                        let s = self.str_from_to(start + BytePos(2), end);
-                        for (idx, c) in s.char_indices() {
-                            let span = self.mk_sp(
-                                start + BytePos::from_usize(2 + idx),
-                                start + BytePos::from_usize(2 + idx + c.len_utf8()),
-                            );
-                            if c != '_' && c.to_digit(base).is_none() {
+                    let guar = self.dcx().emit_err(errors::NoDigitsLiteral { span });
+                    kind = token::Err(guar);
+                } else if matches!(base, Base::Binary | Base::Octal) {
+                    let base = base as u32;
+                    let s = self.str_from_to(start + BytePos(2), end);
+                    for (idx, c) in s.char_indices() {
+                        let span = self.mk_sp(
+                            start + BytePos::from_usize(2 + idx),
+                            start + BytePos::from_usize(2 + idx + c.len_utf8()),
+                        );
+                        if c != '_' && c.to_digit(base).is_none() {
+                            let guar =
                                 self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
-                            }
+                            kind = token::Err(guar);
                         }
                     }
-                    (token::Integer, self.symbol_from_to(start, end))
                 }
+                (kind, self.symbol_from_to(start, end))
             }
             rustc_lexer::LiteralKind::Float { base, empty_exponent } => {
                 if empty_exponent {
@@ -691,7 +692,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
 
     fn cook_common(
         &self,
-        kind: token::LitKind,
+        mut kind: token::LitKind,
         mode: Mode,
         start: BytePos,
         end: BytePos,
@@ -699,7 +700,6 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
         postfix_len: u32,
         unescape: fn(&str, Mode, &mut dyn FnMut(Range<usize>, Result<(), EscapeError>)),
     ) -> (token::LitKind, Symbol) {
-        let mut has_fatal_err = false;
         let content_start = start + BytePos(prefix_len);
         let content_end = end - BytePos(postfix_len);
         let lit_content = self.str_from_to(content_start, content_end);
@@ -711,10 +711,8 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                 let lo = content_start + BytePos(start);
                 let hi = lo + BytePos(end - start);
                 let span = self.mk_sp(lo, hi);
-                if err.is_fatal() {
-                    has_fatal_err = true;
-                }
-                emit_unescape_error(
+                let is_fatal = err.is_fatal();
+                if let Some(guar) = emit_unescape_error(
                     self.dcx(),
                     lit_content,
                     span_with_quotes,
@@ -722,17 +720,21 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
                     mode,
                     range,
                     err,
-                );
+                ) {
+                    assert!(is_fatal);
+                    kind = token::Err(guar);
+                }
             }
         });
 
         // We normally exclude the quotes for the symbol, but for errors we
         // include it because it results in clearer error messages.
-        if !has_fatal_err {
-            (kind, Symbol::intern(lit_content))
+        let sym = if !matches!(kind, token::Err(_)) {
+            Symbol::intern(lit_content)
         } else {
-            (token::Err, self.symbol_from_to(start, end))
-        }
+            self.symbol_from_to(start, end)
+        };
+        (kind, sym)
     }
 
     fn cook_unicode(
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
index 3238f8e23bb..3ebad6a9fd7 100644
--- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
+++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs
@@ -3,7 +3,7 @@
 use std::iter::once;
 use std::ops::Range;
 
-use rustc_errors::{Applicability, DiagCtxt};
+use rustc_errors::{Applicability, DiagCtxt, ErrorGuaranteed};
 use rustc_lexer::unescape::{EscapeError, Mode};
 use rustc_span::{BytePos, Span};
 
@@ -21,7 +21,7 @@ pub(crate) fn emit_unescape_error(
     // range of the error inside `lit`
     range: Range<usize>,
     error: EscapeError,
-) {
+) -> Option<ErrorGuaranteed> {
     debug!(
         "emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}",
         lit, full_lit_span, mode, range, error
@@ -31,12 +31,12 @@ pub(crate) fn emit_unescape_error(
         let span = err_span.with_lo(err_span.hi() - BytePos(c.len_utf8() as u32));
         (c, span)
     };
-    match error {
+    Some(match error {
         EscapeError::LoneSurrogateUnicodeEscape => {
-            dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true });
+            dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true })
         }
         EscapeError::OutOfRangeUnicodeEscape => {
-            dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false });
+            dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false })
         }
         EscapeError::MoreThanOneChar => {
             use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
@@ -106,7 +106,7 @@ pub(crate) fn emit_unescape_error(
                 span: full_lit_span,
                 note,
                 suggestion: sugg,
-            });
+            })
         }
         EscapeError::EscapeOnlyChar => {
             let (c, char_span) = last_char();
@@ -116,15 +116,15 @@ pub(crate) fn emit_unescape_error(
                 escaped_sugg: c.escape_default().to_string(),
                 escaped_msg: escaped_char(c),
                 byte: mode == Mode::Byte,
-            });
+            })
         }
         EscapeError::BareCarriageReturn => {
             let double_quotes = mode.in_double_quotes();
-            dcx.emit_err(UnescapeError::BareCr { span: err_span, double_quotes });
+            dcx.emit_err(UnescapeError::BareCr { span: err_span, double_quotes })
         }
         EscapeError::BareCarriageReturnInRawString => {
             assert!(mode.in_double_quotes());
-            dcx.emit_err(UnescapeError::BareCrRawString(err_span));
+            dcx.emit_err(UnescapeError::BareCrRawString(err_span))
         }
         EscapeError::InvalidEscape => {
             let (c, span) = last_char();
@@ -161,16 +161,14 @@ pub(crate) fn emit_unescape_error(
                      <https://doc.rust-lang.org/reference/tokens.html#literals>",
                 );
             }
-            diag.emit();
-        }
-        EscapeError::TooShortHexEscape => {
-            dcx.emit_err(UnescapeError::TooShortHexEscape(err_span));
+            diag.emit()
         }
+        EscapeError::TooShortHexEscape => dcx.emit_err(UnescapeError::TooShortHexEscape(err_span)),
         EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
             let (c, span) = last_char();
             let is_hex = error == EscapeError::InvalidCharInHexEscape;
             let ch = escaped_char(c);
-            dcx.emit_err(UnescapeError::InvalidCharInEscape { span, is_hex, ch });
+            dcx.emit_err(UnescapeError::InvalidCharInEscape { span, is_hex, ch })
         }
         EscapeError::NonAsciiCharInByte => {
             let (c, span) = last_char();
@@ -213,23 +211,23 @@ pub(crate) fn emit_unescape_error(
                     Applicability::MaybeIncorrect,
                 );
             }
-            err.emit();
+            err.emit()
         }
         EscapeError::OutOfRangeHexEscape => {
-            dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span));
+            dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span))
         }
         EscapeError::LeadingUnderscoreUnicodeEscape => {
             let (c, span) = last_char();
             dcx.emit_err(UnescapeError::LeadingUnderscoreUnicodeEscape {
                 span,
                 ch: escaped_char(c),
-            });
+            })
         }
         EscapeError::OverlongUnicodeEscape => {
-            dcx.emit_err(UnescapeError::OverlongUnicodeEscape(err_span));
+            dcx.emit_err(UnescapeError::OverlongUnicodeEscape(err_span))
         }
         EscapeError::UnclosedUnicodeEscape => {
-            dcx.emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi()));
+            dcx.emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi()))
         }
         EscapeError::NoBraceInUnicodeEscape => {
             let mut suggestion = "\\u{".to_owned();
@@ -248,23 +246,17 @@ pub(crate) fn emit_unescape_error(
             } else {
                 (Some(err_span), NoBraceUnicodeSub::Help)
             };
-            dcx.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub });
+            dcx.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub })
         }
         EscapeError::UnicodeEscapeInByte => {
-            dcx.emit_err(UnescapeError::UnicodeEscapeInByte(err_span));
+            dcx.emit_err(UnescapeError::UnicodeEscapeInByte(err_span))
         }
         EscapeError::EmptyUnicodeEscape => {
-            dcx.emit_err(UnescapeError::EmptyUnicodeEscape(err_span));
-        }
-        EscapeError::ZeroChars => {
-            dcx.emit_err(UnescapeError::ZeroChars(err_span));
-        }
-        EscapeError::LoneSlash => {
-            dcx.emit_err(UnescapeError::LoneSlash(err_span));
-        }
-        EscapeError::NulInCStr => {
-            dcx.emit_err(UnescapeError::NulInCStr { span: err_span });
+            dcx.emit_err(UnescapeError::EmptyUnicodeEscape(err_span))
         }
+        EscapeError::ZeroChars => dcx.emit_err(UnescapeError::ZeroChars(err_span)),
+        EscapeError::LoneSlash => dcx.emit_err(UnescapeError::LoneSlash(err_span)),
+        EscapeError::NulInCStr => dcx.emit_err(UnescapeError::NulInCStr { span: err_span }),
         EscapeError::UnskippedWhitespaceWarning => {
             let (c, char_span) = last_char();
             dcx.emit_warn(UnescapeError::UnskippedWhitespace {
@@ -272,11 +264,13 @@ pub(crate) fn emit_unescape_error(
                 ch: escaped_char(c),
                 char_span,
             });
+            return None;
         }
         EscapeError::MultipleSkippedLinesWarning => {
             dcx.emit_warn(UnescapeError::MultipleSkippedLinesWarning(err_span));
+            return None;
         }
-    }
+    })
 }
 
 /// Pushes a character to a message string for error reporting
diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs
index 445d5b2ce79..69518287f38 100644
--- a/compiler/rustc_parse/src/parser/diagnostics.rs
+++ b/compiler/rustc_parse/src/parser/diagnostics.rs
@@ -46,14 +46,14 @@ use std::ops::{Deref, DerefMut};
 use thin_vec::{thin_vec, ThinVec};
 
 /// Creates a placeholder argument.
-pub(super) fn dummy_arg(ident: Ident) -> Param {
+pub(super) fn dummy_arg(ident: Ident, guar: ErrorGuaranteed) -> Param {
     let pat = P(Pat {
         id: ast::DUMMY_NODE_ID,
         kind: PatKind::Ident(BindingAnnotation::NONE, ident, None),
         span: ident.span,
         tokens: None,
     });
-    let ty = Ty { kind: TyKind::Err, span: ident.span, id: ast::DUMMY_NODE_ID, tokens: None };
+    let ty = Ty { kind: TyKind::Err(guar), span: ident.span, id: ast::DUMMY_NODE_ID, tokens: None };
     Param {
         attrs: AttrVec::default(),
         id: ast::DUMMY_NODE_ID,
@@ -1540,14 +1540,14 @@ impl<'a> Parser<'a> {
     pub(super) fn maybe_recover_from_question_mark(&mut self, ty: P<Ty>) -> P<Ty> {
         if self.token == token::Question {
             self.bump();
-            self.dcx().emit_err(QuestionMarkInType {
+            let guar = self.dcx().emit_err(QuestionMarkInType {
                 span: self.prev_token.span,
                 sugg: QuestionMarkInTypeSugg {
                     left: ty.span.shrink_to_lo(),
                     right: self.prev_token.span,
                 },
             });
-            self.mk_ty(ty.span.to(self.prev_token.span), TyKind::Err)
+            self.mk_ty(ty.span.to(self.prev_token.span), TyKind::Err(guar))
         } else {
             ty
         }
@@ -2304,8 +2304,8 @@ impl<'a> Parser<'a> {
 
     pub(super) fn recover_bad_self_param(&mut self, mut param: Param) -> PResult<'a, Param> {
         let span = param.pat.span;
-        param.ty.kind = TyKind::Err;
-        self.dcx().emit_err(SelfParamNotFirst { span });
+        let guar = self.dcx().emit_err(SelfParamNotFirst { span });
+        param.ty.kind = TyKind::Err(guar);
         Ok(param)
     }
 
@@ -2437,7 +2437,7 @@ impl<'a> Parser<'a> {
     pub(super) fn deduplicate_recovered_params_names(&self, fn_inputs: &mut ThinVec<Param>) {
         let mut seen_inputs = FxHashSet::default();
         for input in fn_inputs.iter_mut() {
-            let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err) =
+            let opt_ident = if let (PatKind::Ident(_, ident, _), TyKind::Err(_)) =
                 (&input.pat.kind, &input.ty.kind)
             {
                 Some(*ident)
@@ -2644,8 +2644,10 @@ impl<'a> Parser<'a> {
                         "::",
                         Applicability::MaybeIncorrect,
                     );
-                    err.emit();
-                    return Ok(GenericArg::Type(self.mk_ty(start.to(expr.span), TyKind::Err)));
+                    let guar = err.emit();
+                    return Ok(GenericArg::Type(
+                        self.mk_ty(start.to(expr.span), TyKind::Err(guar)),
+                    ));
                 } else if token::Comma == self.token.kind || self.token.kind.should_end_const_arg()
                 {
                     // Avoid the following output by checking that we consumed a full const arg:
diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs
index 1a57474bac2..2424b6c130d 100644
--- a/compiler/rustc_parse/src/parser/expr.rs
+++ b/compiler/rustc_parse/src/parser/expr.rs
@@ -2140,12 +2140,12 @@ impl<'a> Parser<'a> {
                     Err(err) => {
                         let span = token.uninterpolated_span();
                         self.bump();
-                        report_lit_error(self.sess, err, lit, span);
+                        let guar = report_lit_error(self.sess, err, lit, span);
                         // Pack possible quotes and prefixes from the original literal into
                         // the error literal's symbol so they can be pretty-printed faithfully.
                         let suffixless_lit = token::Lit::new(lit.kind, lit.symbol, None);
                         let symbol = Symbol::intern(&suffixless_lit.to_string());
-                        let lit = token::Lit::new(token::Err, symbol, lit.suffix);
+                        let lit = token::Lit::new(token::Err(guar), symbol, lit.suffix);
                         Some(
                             MetaItemLit::from_token_lit(lit, span)
                                 .unwrap_or_else(|_| unreachable!()),
diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs
index 8050b34956c..a0605b8a44c 100644
--- a/compiler/rustc_parse/src/parser/item.rs
+++ b/compiler/rustc_parse/src/parser/item.rs
@@ -591,7 +591,23 @@ impl<'a> Parser<'a> {
         let ty_second = if self.token == token::DotDot {
             // We need to report this error after `cfg` expansion for compatibility reasons
             self.bump(); // `..`, do not add it to expected tokens
-            Some(self.mk_ty(self.prev_token.span, TyKind::Err))
+
+            // FIXME(nnethercote): AST validation later detects this
+            // `TyKind::Err` and emits an errors. So why the unchecked
+            // ErrorGuaranteed?
+            // - A `span_delayed_bug` doesn't work here, because rustfmt can
+            //   hit this path but then not hit the follow-up path in the AST
+            //   validator that issues the error, which results in ICEs.
+            // - `TyKind::Dummy` doesn't work, because it ends up reaching HIR
+            //   lowering, which results in ICEs. Changing `TyKind::Dummy` to
+            //   `TyKind::Err` during AST validation might fix that, but that's
+            //   not possible because AST validation doesn't allow mutability.
+            //
+            // #121072 will hopefully remove all this special handling of the
+            // obsolete `impl Trait for ..` and then this can go away.
+            #[allow(deprecated)]
+            let guar = rustc_errors::ErrorGuaranteed::unchecked_error_guaranteed();
+            Some(self.mk_ty(self.prev_token.span, TyKind::Err(guar)))
         } else if has_for || self.token.can_begin_type() {
             Some(self.parse_ty()?)
         } else {
@@ -2628,13 +2644,13 @@ impl<'a> Parser<'a> {
             p.recover_diff_marker();
             let snapshot = p.create_snapshot_for_diagnostic();
             let param = p.parse_param_general(req_name, first_param).or_else(|e| {
-                e.emit();
+                let guar = e.emit();
                 let lo = p.prev_token.span;
                 p.restore_snapshot(snapshot);
                 // Skip every token until next possible arg or end.
                 p.eat_to_tokens(&[&token::Comma, &token::CloseDelim(Delimiter::Parenthesis)]);
                 // Create a placeholder argument for proper arg count (issue #34264).
-                Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span))))
+                Ok(dummy_arg(Ident::new(kw::Empty, lo.to(p.prev_token.span)), guar))
             });
             // ...now that we've parsed the first argument, `self` is no longer allowed.
             first_param = false;
@@ -2671,8 +2687,8 @@ impl<'a> Parser<'a> {
                     return if let Some(ident) =
                         this.parameter_without_type(&mut err, pat, is_name_required, first_param)
                     {
-                        err.emit();
-                        Ok((dummy_arg(ident), TrailingToken::None))
+                        let guar = err.emit();
+                        Ok((dummy_arg(ident, guar), TrailingToken::None))
                     } else {
                         Err(err)
                     };
diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs
index 623407eb380..dea2b9e6ca7 100644
--- a/compiler/rustc_parse/src/parser/mod.rs
+++ b/compiler/rustc_parse/src/parser/mod.rs
@@ -1459,7 +1459,7 @@ impl<'a> Parser<'a> {
         match self.parse_str_lit() {
             Ok(str_lit) => Some(str_lit),
             Err(Some(lit)) => match lit.kind {
-                ast::LitKind::Err => None,
+                ast::LitKind::Err(_) => None,
                 _ => {
                     self.dcx().emit_err(NonStringAbiLiteral { span: lit.span });
                     None
diff --git a/compiler/rustc_parse/src/parser/path.rs b/compiler/rustc_parse/src/parser/path.rs
index e7cad74b4dd..681039999a6 100644
--- a/compiler/rustc_parse/src/parser/path.rs
+++ b/compiler/rustc_parse/src/parser/path.rs
@@ -678,8 +678,9 @@ impl<'a> Parser<'a> {
                 c.into()
             }
             Some(GenericArg::Lifetime(lt)) => {
-                self.dcx().emit_err(errors::AssocLifetime { span, lifetime: lt.ident.span });
-                self.mk_ty(span, ast::TyKind::Err).into()
+                let guar =
+                    self.dcx().emit_err(errors::AssocLifetime { span, lifetime: lt.ident.span });
+                self.mk_ty(span, ast::TyKind::Err(guar)).into()
             }
             None => {
                 let after_eq = eq.shrink_to_hi();
@@ -779,7 +780,7 @@ impl<'a> Parser<'a> {
                     // type to determine if error recovery has occurred and if the input is not a
                     // syntactically valid type after all.
                     if let ast::TyKind::Slice(inner_ty) | ast::TyKind::Array(inner_ty, _) = &ty.kind
-                        && let ast::TyKind::Err = inner_ty.kind
+                        && let ast::TyKind::Err(_) = inner_ty.kind
                         && let Some(snapshot) = snapshot
                         && let Some(expr) =
                             self.recover_unbraced_const_arg_that_can_begin_ty(snapshot)
diff --git a/compiler/rustc_parse/src/parser/ty.rs b/compiler/rustc_parse/src/parser/ty.rs
index 157fb9e505a..f79f2a813b2 100644
--- a/compiler/rustc_parse/src/parser/ty.rs
+++ b/compiler/rustc_parse/src/parser/ty.rs
@@ -346,8 +346,10 @@ impl<'a> Parser<'a> {
                 AllowCVariadic::No => {
                     // FIXME(Centril): Should we just allow `...` syntactically
                     // anywhere in a type and use semantic restrictions instead?
-                    self.dcx().emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) });
-                    TyKind::Err
+                    let guar = self
+                        .dcx()
+                        .emit_err(NestedCVariadicType { span: lo.to(self.prev_token.span) });
+                    TyKind::Err(guar)
                 }
             }
         } else {
@@ -493,8 +495,8 @@ impl<'a> Parser<'a> {
             {
                 // Recover from `[LIT; EXPR]` and `[LIT]`
                 self.bump();
-                err.emit();
-                self.mk_ty(self.prev_token.span, TyKind::Err)
+                let guar = err.emit();
+                self.mk_ty(self.prev_token.span, TyKind::Err(guar))
             }
             Err(err) => return Err(err),
         };
diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs
index 2fafbd6d97b..b0982029657 100644
--- a/compiler/rustc_parse/src/validate_attr.rs
+++ b/compiler/rustc_parse/src/validate_attr.rs
@@ -70,11 +70,11 @@ pub fn parse_meta<'a>(sess: &'a ParseSess, attr: &Attribute) -> PResult<'a, Meta
                             }
                         }
                         Err(err) => {
-                            report_lit_error(sess, err, token_lit, expr.span);
+                            let guar = report_lit_error(sess, err, token_lit, expr.span);
                             let lit = ast::MetaItemLit {
                                 symbol: token_lit.symbol,
                                 suffix: token_lit.suffix,
-                                kind: ast::LitKind::Err,
+                                kind: ast::LitKind::Err(guar),
                                 span: expr.span,
                             };
                             MetaItemKind::NameValue(lit)
diff --git a/compiler/rustc_passes/src/hir_stats.rs b/compiler/rustc_passes/src/hir_stats.rs
index d02e86dd456..96429bb7788 100644
--- a/compiler/rustc_passes/src/hir_stats.rs
+++ b/compiler/rustc_passes/src/hir_stats.rs
@@ -616,8 +616,9 @@ impl<'v> ast_visit::Visitor<'v> for StatCollector<'v> {
                 Infer,
                 ImplicitSelf,
                 MacCall,
-                Err,
-                CVarArgs
+                CVarArgs,
+                Dummy,
+                Err
             ]
         );
 
diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs
index c36cec6f353..82846e3b4e8 100644
--- a/compiler/rustc_session/src/errors.rs
+++ b/compiler/rustc_session/src/errors.rs
@@ -3,7 +3,8 @@ use std::num::NonZeroU32;
 use rustc_ast::token;
 use rustc_ast::util::literal::LitError;
 use rustc_errors::{
-    codes::*, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, IntoDiagnostic, Level, MultiSpan,
+    codes::*, DiagCtxt, DiagnosticBuilder, DiagnosticMessage, ErrorGuaranteed, IntoDiagnostic,
+    Level, MultiSpan,
 };
 use rustc_macros::Diagnostic;
 use rustc_span::{Span, Symbol};
@@ -344,7 +345,12 @@ pub(crate) struct BinaryFloatLiteralNotSupported {
     pub span: Span,
 }
 
-pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) {
+pub fn report_lit_error(
+    sess: &ParseSess,
+    err: LitError,
+    lit: token::Lit,
+    span: Span,
+) -> ErrorGuaranteed {
     // Checks if `s` looks like i32 or u1234 etc.
     fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
         s.len() > 1 && s.starts_with(first_chars) && s[1..].chars().all(|c| c.is_ascii_digit())
@@ -372,47 +378,37 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
         valid.then(|| format!("0{}{}", base_char.to_ascii_lowercase(), &suffix[1..]))
     }
 
-    let token::Lit { kind, symbol, suffix, .. } = lit;
     let dcx = &sess.dcx;
     match err {
-        // `LexerError` is an error, but it was already reported
-        // by lexer, so here we don't report it the second time.
-        LitError::LexerError => {}
-        LitError::InvalidSuffix => {
-            if let Some(suffix) = suffix {
-                dcx.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix });
-            }
+        LitError::InvalidSuffix(suffix) => {
+            dcx.emit_err(InvalidLiteralSuffix { span, kind: lit.kind.descr(), suffix })
         }
-        LitError::InvalidIntSuffix => {
-            let suf = suffix.expect("suffix error with no suffix");
-            let suf = suf.as_str();
+        LitError::InvalidIntSuffix(suffix) => {
+            let suf = suffix.as_str();
             if looks_like_width_suffix(&['i', 'u'], suf) {
                 // If it looks like a width, try to be helpful.
-                dcx.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() });
-            } else if let Some(fixed) = fix_base_capitalisation(symbol.as_str(), suf) {
-                dcx.emit_err(InvalidNumLiteralBasePrefix { span, fixed });
+                dcx.emit_err(InvalidIntLiteralWidth { span, width: suf[1..].into() })
+            } else if let Some(fixed) = fix_base_capitalisation(lit.symbol.as_str(), suf) {
+                dcx.emit_err(InvalidNumLiteralBasePrefix { span, fixed })
             } else {
-                dcx.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() });
+                dcx.emit_err(InvalidNumLiteralSuffix { span, suffix: suf.to_string() })
             }
         }
-        LitError::InvalidFloatSuffix => {
-            let suf = suffix.expect("suffix error with no suffix");
-            let suf = suf.as_str();
+        LitError::InvalidFloatSuffix(suffix) => {
+            let suf = suffix.as_str();
             if looks_like_width_suffix(&['f'], suf) {
                 // If it looks like a width, try to be helpful.
-                dcx.emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() });
+                dcx.emit_err(InvalidFloatLiteralWidth { span, width: suf[1..].to_string() })
             } else {
-                dcx.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() });
+                dcx.emit_err(InvalidFloatLiteralSuffix { span, suffix: suf.to_string() })
             }
         }
-        LitError::NonDecimalFloat(base) => {
-            match base {
-                16 => dcx.emit_err(HexadecimalFloatLiteralNotSupported { span }),
-                8 => dcx.emit_err(OctalFloatLiteralNotSupported { span }),
-                2 => dcx.emit_err(BinaryFloatLiteralNotSupported { span }),
-                _ => unreachable!(),
-            };
-        }
+        LitError::NonDecimalFloat(base) => match base {
+            16 => dcx.emit_err(HexadecimalFloatLiteralNotSupported { span }),
+            8 => dcx.emit_err(OctalFloatLiteralNotSupported { span }),
+            2 => dcx.emit_err(BinaryFloatLiteralNotSupported { span }),
+            _ => unreachable!(),
+        },
         LitError::IntTooLarge(base) => {
             let max = u128::MAX;
             let limit = match base {
@@ -421,7 +417,7 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
                 16 => format!("{max:#x}"),
                 _ => format!("{max}"),
             };
-            dcx.emit_err(IntLiteralTooLarge { span, limit });
+            dcx.emit_err(IntLiteralTooLarge { span, limit })
         }
     }
 }
diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs
index 8adb0cbcc9d..288e0a5ca6f 100644
--- a/compiler/rustc_session/src/parse.rs
+++ b/compiler/rustc_session/src/parse.rs
@@ -11,7 +11,7 @@ use crate::lint::{
 };
 use crate::Session;
 use rustc_ast::node_id::NodeId;
-use rustc_data_structures::fx::{FxHashMap, FxHashSet};
+use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet};
 use rustc_data_structures::sync::{AppendOnlyVec, Lock, Lrc};
 use rustc_errors::{emitter::SilentEmitter, DiagCtxt};
 use rustc_errors::{
@@ -205,19 +205,19 @@ pub struct ParseSess {
     /// Places where identifiers that contain invalid Unicode codepoints but that look like they
     /// should be. Useful to avoid bad tokenization when encountering emoji. We group them to
     /// provide a single error per unique incorrect identifier.
-    pub bad_unicode_identifiers: Lock<FxHashMap<Symbol, Vec<Span>>>,
+    pub bad_unicode_identifiers: Lock<FxIndexMap<Symbol, Vec<Span>>>,
     source_map: Lrc<SourceMap>,
     pub buffered_lints: Lock<Vec<BufferedEarlyLint>>,
     /// Contains the spans of block expressions that could have been incomplete based on the
     /// operation token that followed it, but that the parser cannot identify without further
     /// analysis.
-    pub ambiguous_block_expr_parse: Lock<FxHashMap<Span, Span>>,
+    pub ambiguous_block_expr_parse: Lock<FxIndexMap<Span, Span>>,
     pub gated_spans: GatedSpans,
     pub symbol_gallery: SymbolGallery,
     /// Environment variables accessed during the build and their values when they exist.
-    pub env_depinfo: Lock<FxHashSet<(Symbol, Option<Symbol>)>>,
+    pub env_depinfo: Lock<FxIndexSet<(Symbol, Option<Symbol>)>>,
     /// File paths accessed during the build.
-    pub file_depinfo: Lock<FxHashSet<Symbol>>,
+    pub file_depinfo: Lock<FxIndexSet<Symbol>>,
     /// Whether cfg(version) should treat the current release as incomplete
     pub assume_incomplete_release: bool,
     /// Spans passed to `proc_macro::quote_span`. Each span has a numerical
@@ -247,7 +247,7 @@ impl ParseSess {
             bad_unicode_identifiers: Lock::new(Default::default()),
             source_map,
             buffered_lints: Lock::new(vec![]),
-            ambiguous_block_expr_parse: Lock::new(FxHashMap::default()),
+            ambiguous_block_expr_parse: Lock::new(Default::default()),
             gated_spans: GatedSpans::default(),
             symbol_gallery: SymbolGallery::default(),
             env_depinfo: Default::default(),
diff --git a/compiler/rustc_trait_selection/messages.ftl b/compiler/rustc_trait_selection/messages.ftl
index 41db8059cbe..0dcba0e05f7 100644
--- a/compiler/rustc_trait_selection/messages.ftl
+++ b/compiler/rustc_trait_selection/messages.ftl
@@ -8,14 +8,16 @@ trait_selection_adjust_signature_remove_borrow = consider adjusting the signatur
         *[other] arguments
     }
 
-trait_selection_closure_fn_mut_label = closure is `FnMut` because it mutates the variable `{$place}` here
+trait_selection_async_closure_not_fn = async closure does not implement `{$kind}` because it captures state from its environment
 
-trait_selection_closure_fn_once_label = closure is `FnOnce` because it moves the variable `{$place}` out of its environment
+trait_selection_closure_fn_mut_label = closure is `{$trait_prefix}FnMut` because it mutates the variable `{$place}` here
 
-trait_selection_closure_kind_mismatch = expected a closure that implements the `{$expected}` trait, but this closure only implements `{$found}`
-    .label = this closure implements `{$found}`, not `{$expected}`
+trait_selection_closure_fn_once_label = closure is `{$trait_prefix}FnOnce` because it moves the variable `{$place}` out of its environment
 
-trait_selection_closure_kind_requirement = the requirement to implement `{$expected}` derives from here
+trait_selection_closure_kind_mismatch = expected a closure that implements the `{$trait_prefix}{$expected}` trait, but this closure only implements `{$trait_prefix}{$found}`
+    .label = this closure implements `{$trait_prefix}{$found}`, not `{$trait_prefix}{$expected}`
+
+trait_selection_closure_kind_requirement = the requirement to implement `{$trait_prefix}{$expected}` derives from here
 
 trait_selection_dump_vtable_entries = vtable entries for `{$trait_ref}`: {$entries}
 
diff --git a/compiler/rustc_trait_selection/src/errors.rs b/compiler/rustc_trait_selection/src/errors.rs
index 20cd573f46e..407fff03e15 100644
--- a/compiler/rustc_trait_selection/src/errors.rs
+++ b/compiler/rustc_trait_selection/src/errors.rs
@@ -135,6 +135,8 @@ pub struct ClosureKindMismatch {
     #[label(trait_selection_closure_kind_requirement)]
     pub cause_span: Span,
 
+    pub trait_prefix: &'static str,
+
     #[subdiagnostic]
     pub fn_once_label: Option<ClosureFnOnceLabel>,
 
@@ -157,3 +159,11 @@ pub struct ClosureFnMutLabel {
     pub span: Span,
     pub place: String,
 }
+
+#[derive(Diagnostic)]
+#[diag(trait_selection_async_closure_not_fn)]
+pub(crate) struct AsyncClosureNotFn {
+    #[primary_span]
+    pub span: Span,
+    pub kind: &'static str,
+}
diff --git a/compiler/rustc_trait_selection/src/solve/trait_goals.rs b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
index eacdd9fde51..73bf66f6689 100644
--- a/compiler/rustc_trait_selection/src/solve/trait_goals.rs
+++ b/compiler/rustc_trait_selection/src/solve/trait_goals.rs
@@ -1,7 +1,10 @@
 //! Dealing with trait goals, i.e. `T: Trait<'a, U>`.
 
+use crate::traits::supertrait_def_ids;
+
 use super::assembly::{self, structural_traits, Candidate};
 use super::{EvalCtxt, GoalSource, SolverMode};
+use rustc_data_structures::fx::FxIndexSet;
 use rustc_hir::def_id::DefId;
 use rustc_hir::{LangItem, Movability};
 use rustc_infer::traits::query::NoSolution;
@@ -663,13 +666,6 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
         let tcx = self.tcx();
         let Goal { predicate: (a_ty, _b_ty), .. } = goal;
 
-        // All of a's auto traits need to be in b's auto traits.
-        let auto_traits_compatible =
-            b_data.auto_traits().all(|b| a_data.auto_traits().any(|a| a == b));
-        if !auto_traits_compatible {
-            return vec![];
-        }
-
         let mut responses = vec![];
         // If the principal def ids match (or are both none), then we're not doing
         // trait upcasting. We're just removing auto traits (or shortening the lifetime).
@@ -757,6 +753,17 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
     ) -> QueryResult<'tcx> {
         let param_env = goal.param_env;
 
+        // We may upcast to auto traits that are either explicitly listed in
+        // the object type's bounds, or implied by the principal trait ref's
+        // supertraits.
+        let a_auto_traits: FxIndexSet<DefId> = a_data
+            .auto_traits()
+            .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
+                supertrait_def_ids(self.tcx(), principal_def_id)
+                    .filter(|def_id| self.tcx().trait_is_auto(*def_id))
+            }))
+            .collect();
+
         // More than one projection in a_ty's bounds may match the projection
         // in b_ty's bound. Use this to first determine *which* apply without
         // having any inference side-effects. We process obligations because
@@ -806,7 +813,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
                 }
                 // Check that b_ty's auto traits are present in a_ty's bounds.
                 ty::ExistentialPredicate::AutoTrait(def_id) => {
-                    if !a_data.auto_traits().any(|source_def_id| source_def_id == def_id) {
+                    if !a_auto_traits.contains(&def_id) {
                         return Err(NoSolution);
                     }
                 }
diff --git a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
index 73effb33560..68b1a0d4e61 100644
--- a/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
+++ b/compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs
@@ -2,7 +2,9 @@
 
 use super::on_unimplemented::{AppendConstMessage, OnUnimplementedNote, TypeErrCtxtExt as _};
 use super::suggestions::{get_explanation_based_on_obligation, TypeErrCtxtExt as _};
-use crate::errors::{ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch};
+use crate::errors::{
+    AsyncClosureNotFn, ClosureFnMutLabel, ClosureFnOnceLabel, ClosureKindMismatch,
+};
 use crate::infer::error_reporting::{TyCategory, TypeAnnotationNeeded as ErrorCode};
 use crate::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
 use crate::infer::InferCtxtExt as _;
@@ -959,34 +961,102 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
     fn emit_specialized_closure_kind_error(
         &self,
         obligation: &PredicateObligation<'tcx>,
-        trait_ref: ty::PolyTraitRef<'tcx>,
+        mut trait_ref: ty::PolyTraitRef<'tcx>,
     ) -> Option<ErrorGuaranteed> {
-        let self_ty = trait_ref.self_ty().skip_binder();
-        if let ty::Closure(closure_def_id, closure_args) = *self_ty.kind()
-            && let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id())
-            && let Some(found_kind) = self.closure_kind(self_ty)
+        // If `AsyncFnKindHelper` is not implemented, that means that the closure kind
+        // doesn't extend the goal kind. This is worth reporting, but we can only do so
+        // if we actually know which closure this goal comes from, so look at the cause
+        // to see if we can extract that information.
+        if Some(trait_ref.def_id()) == self.tcx.lang_items().async_fn_kind_helper()
+            && let Some(found_kind) = trait_ref.skip_binder().args.type_at(0).to_opt_closure_kind()
+            && let Some(expected_kind) =
+                trait_ref.skip_binder().args.type_at(1).to_opt_closure_kind()
             && !found_kind.extends(expected_kind)
-            && let sig = closure_args.as_closure().sig()
-            && self.can_sub(
-                obligation.param_env,
-                trait_ref,
-                sig.map_bound(|sig| {
-                    ty::TraitRef::new(
-                        self.tcx,
-                        trait_ref.def_id(),
-                        [trait_ref.self_ty().skip_binder(), sig.inputs()[0]],
-                    )
-                }),
-            )
         {
-            let mut err =
-                self.report_closure_error(&obligation, closure_def_id, found_kind, expected_kind);
-            self.note_obligation_cause(&mut err, &obligation);
-            self.point_at_returns_when_relevant(&mut err, &obligation);
-            Some(err.emit())
-        } else {
-            None
+            if let Some((_, Some(parent))) = obligation.cause.code().parent() {
+                // If we have a derived obligation, then the parent will be a `AsyncFn*` goal.
+                trait_ref = parent.to_poly_trait_ref();
+            } else if let &ObligationCauseCode::FunctionArgumentObligation { arg_hir_id, .. } =
+                obligation.cause.code()
+                && let Some(typeck_results) = &self.typeck_results
+                && let ty::Closure(closure_def_id, _) | ty::CoroutineClosure(closure_def_id, _) =
+                    *typeck_results.node_type(arg_hir_id).kind()
+            {
+                // Otherwise, extract the closure kind from the obligation.
+                let mut err = self.report_closure_error(
+                    &obligation,
+                    closure_def_id,
+                    found_kind,
+                    expected_kind,
+                    "async ",
+                );
+                self.note_obligation_cause(&mut err, &obligation);
+                self.point_at_returns_when_relevant(&mut err, &obligation);
+                return Some(err.emit());
+            }
+        }
+
+        let self_ty = trait_ref.self_ty().skip_binder();
+
+        if let Some(expected_kind) = self.tcx.fn_trait_kind_from_def_id(trait_ref.def_id()) {
+            let (closure_def_id, found_args, by_ref_captures) = match *self_ty.kind() {
+                ty::Closure(def_id, args) => {
+                    (def_id, args.as_closure().sig().map_bound(|sig| sig.inputs()[0]), None)
+                }
+                ty::CoroutineClosure(def_id, args) => (
+                    def_id,
+                    args.as_coroutine_closure()
+                        .coroutine_closure_sig()
+                        .map_bound(|sig| sig.tupled_inputs_ty),
+                    Some(args.as_coroutine_closure().coroutine_captures_by_ref_ty()),
+                ),
+                _ => return None,
+            };
+
+            let expected_args = trait_ref.map_bound(|trait_ref| trait_ref.args.type_at(1));
+
+            // Verify that the arguments are compatible. If the signature is
+            // mismatched, then we have a totally different error to report.
+            if self.enter_forall(found_args, |found_args| {
+                self.enter_forall(expected_args, |expected_args| {
+                    !self.can_sub(obligation.param_env, expected_args, found_args)
+                })
+            }) {
+                return None;
+            }
+
+            if let Some(found_kind) = self.closure_kind(self_ty)
+                && !found_kind.extends(expected_kind)
+            {
+                let mut err = self.report_closure_error(
+                    &obligation,
+                    closure_def_id,
+                    found_kind,
+                    expected_kind,
+                    "",
+                );
+                self.note_obligation_cause(&mut err, &obligation);
+                self.point_at_returns_when_relevant(&mut err, &obligation);
+                return Some(err.emit());
+            }
+
+            // If the closure has captures, then perhaps the reason that the trait
+            // is unimplemented is because async closures don't implement `Fn`/`FnMut`
+            // if they have captures.
+            if let Some(by_ref_captures) = by_ref_captures
+                && let ty::FnPtr(sig) = by_ref_captures.kind()
+                && !sig.skip_binder().output().is_unit()
+            {
+                let mut err = self.tcx.dcx().create_err(AsyncClosureNotFn {
+                    span: self.tcx.def_span(closure_def_id),
+                    kind: expected_kind.as_str(),
+                });
+                self.note_obligation_cause(&mut err, &obligation);
+                self.point_at_returns_when_relevant(&mut err, &obligation);
+                return Some(err.emit());
+            }
         }
+        None
     }
 
     fn fn_arg_obligation(
@@ -1493,6 +1563,7 @@ pub(super) trait InferCtxtPrivExt<'tcx> {
         closure_def_id: DefId,
         found_kind: ty::ClosureKind,
         kind: ty::ClosureKind,
+        trait_prefix: &'static str,
     ) -> DiagnosticBuilder<'tcx>;
 
     fn report_cyclic_signature_error(
@@ -3376,6 +3447,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
         closure_def_id: DefId,
         found_kind: ty::ClosureKind,
         kind: ty::ClosureKind,
+        trait_prefix: &'static str,
     ) -> DiagnosticBuilder<'tcx> {
         let closure_span = self.tcx.def_span(closure_def_id);
 
@@ -3384,6 +3456,7 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
             expected: kind,
             found: found_kind,
             cause_span: obligation.cause.span,
+            trait_prefix,
             fn_once_label: None,
             fn_mut_label: None,
         };
diff --git a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
index 149dc4c75a7..39f4ceda9f1 100644
--- a/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs
@@ -10,7 +10,7 @@ use std::ops::ControlFlow;
 
 use hir::def_id::DefId;
 use hir::LangItem;
-use rustc_data_structures::fx::FxHashSet;
+use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
 use rustc_hir as hir;
 use rustc_infer::traits::ObligationCause;
 use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
@@ -968,52 +968,61 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
                 //
                 // We always perform upcasting coercions when we can because of reason
                 // #2 (region bounds).
-                let auto_traits_compatible = b_data
-                    .auto_traits()
-                    // All of a's auto traits need to be in b's auto traits.
-                    .all(|b| a_data.auto_traits().any(|a| a == b));
-                if auto_traits_compatible {
-                    let principal_def_id_a = a_data.principal_def_id();
-                    let principal_def_id_b = b_data.principal_def_id();
-                    if principal_def_id_a == principal_def_id_b {
-                        // no cyclic
+                let principal_def_id_a = a_data.principal_def_id();
+                let principal_def_id_b = b_data.principal_def_id();
+                if principal_def_id_a == principal_def_id_b {
+                    // We may upcast to auto traits that are either explicitly listed in
+                    // the object type's bounds, or implied by the principal trait ref's
+                    // supertraits.
+                    let a_auto_traits: FxIndexSet<DefId> = a_data
+                        .auto_traits()
+                        .chain(principal_def_id_a.into_iter().flat_map(|principal_def_id| {
+                            util::supertrait_def_ids(self.tcx(), principal_def_id)
+                                .filter(|def_id| self.tcx().trait_is_auto(*def_id))
+                        }))
+                        .collect();
+                    let auto_traits_compatible = b_data
+                        .auto_traits()
+                        // All of a's auto traits need to be in b's auto traits.
+                        .all(|b| a_auto_traits.contains(&b));
+                    if auto_traits_compatible {
                         candidates.vec.push(BuiltinUnsizeCandidate);
-                    } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
-                        // not casual unsizing, now check whether this is trait upcasting coercion.
-                        let principal_a = a_data.principal().unwrap();
-                        let target_trait_did = principal_def_id_b.unwrap();
-                        let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
-                        if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
-                            source,
-                            obligation.param_env,
-                            &obligation.cause,
-                        ) {
-                            if deref_trait_ref.def_id() == target_trait_did {
-                                return;
-                            }
+                    }
+                } else if principal_def_id_a.is_some() && principal_def_id_b.is_some() {
+                    // not casual unsizing, now check whether this is trait upcasting coercion.
+                    let principal_a = a_data.principal().unwrap();
+                    let target_trait_did = principal_def_id_b.unwrap();
+                    let source_trait_ref = principal_a.with_self_ty(self.tcx(), source);
+                    if let Some(deref_trait_ref) = self.need_migrate_deref_output_trait_object(
+                        source,
+                        obligation.param_env,
+                        &obligation.cause,
+                    ) {
+                        if deref_trait_ref.def_id() == target_trait_did {
+                            return;
                         }
+                    }
 
-                        for (idx, upcast_trait_ref) in
-                            util::supertraits(self.tcx(), source_trait_ref).enumerate()
-                        {
-                            self.infcx.probe(|_| {
-                                if upcast_trait_ref.def_id() == target_trait_did
-                                    && let Ok(nested) = self.match_upcast_principal(
-                                        obligation,
-                                        upcast_trait_ref,
-                                        a_data,
-                                        b_data,
-                                        a_region,
-                                        b_region,
-                                    )
-                                {
-                                    if nested.is_none() {
-                                        candidates.ambiguous = true;
-                                    }
-                                    candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
+                    for (idx, upcast_trait_ref) in
+                        util::supertraits(self.tcx(), source_trait_ref).enumerate()
+                    {
+                        self.infcx.probe(|_| {
+                            if upcast_trait_ref.def_id() == target_trait_did
+                                && let Ok(nested) = self.match_upcast_principal(
+                                    obligation,
+                                    upcast_trait_ref,
+                                    a_data,
+                                    b_data,
+                                    a_region,
+                                    b_region,
+                                )
+                            {
+                                if nested.is_none() {
+                                    candidates.ambiguous = true;
                                 }
-                            })
-                        }
+                                candidates.vec.push(TraitUpcastingUnsizeCandidate(idx));
+                            }
+                        })
                     }
                 }
             }
diff --git a/compiler/rustc_trait_selection/src/traits/select/mod.rs b/compiler/rustc_trait_selection/src/traits/select/mod.rs
index ab0c53e6a9b..5bcf46a96ed 100644
--- a/compiler/rustc_trait_selection/src/traits/select/mod.rs
+++ b/compiler/rustc_trait_selection/src/traits/select/mod.rs
@@ -2526,6 +2526,17 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
         let tcx = self.tcx();
         let mut nested = vec![];
 
+        // We may upcast to auto traits that are either explicitly listed in
+        // the object type's bounds, or implied by the principal trait ref's
+        // supertraits.
+        let a_auto_traits: FxIndexSet<DefId> = a_data
+            .auto_traits()
+            .chain(a_data.principal_def_id().into_iter().flat_map(|principal_def_id| {
+                util::supertrait_def_ids(tcx, principal_def_id)
+                    .filter(|def_id| tcx.trait_is_auto(*def_id))
+            }))
+            .collect();
+
         let upcast_principal = normalize_with_depth_to(
             self,
             obligation.param_env,
@@ -2588,7 +2599,7 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
                 }
                 // Check that b_ty's auto traits are present in a_ty's bounds.
                 ty::ExistentialPredicate::AutoTrait(def_id) => {
-                    if !a_data.auto_traits().any(|source_def_id| source_def_id == def_id) {
+                    if !a_auto_traits.contains(&def_id) {
                         return Err(SelectionError::Unimplemented);
                     }
                 }
diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs
index 2b8ddf14ff3..addcc71a2d4 100644
--- a/library/alloc/src/collections/btree/map.rs
+++ b/library/alloc/src/collections/btree/map.rs
@@ -3247,9 +3247,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
     #[unstable(feature = "btree_cursors", issue = "107540")]
     pub fn remove_next(&mut self) -> Option<(K, V)> {
         let current = self.current.take()?;
+        if current.reborrow().next_kv().is_err() {
+            self.current = Some(current);
+            return None;
+        }
         let mut emptied_internal_root = false;
         let (kv, pos) = current
             .next_kv()
+            // This should be unwrap(), but that doesn't work because NodeRef
+            // doesn't implement Debug. The condition is checked above.
             .ok()?
             .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
         self.current = Some(pos);
@@ -3270,9 +3276,15 @@ impl<'a, K: Ord, V, A: Allocator + Clone> CursorMutKey<'a, K, V, A> {
     #[unstable(feature = "btree_cursors", issue = "107540")]
     pub fn remove_prev(&mut self) -> Option<(K, V)> {
         let current = self.current.take()?;
+        if current.reborrow().next_back_kv().is_err() {
+            self.current = Some(current);
+            return None;
+        }
         let mut emptied_internal_root = false;
         let (kv, pos) = current
             .next_back_kv()
+            // This should be unwrap(), but that doesn't work because NodeRef
+            // doesn't implement Debug. The condition is checked above.
             .ok()?
             .remove_kv_tracking(|| emptied_internal_root = true, self.alloc.clone());
         self.current = Some(pos);
diff --git a/library/alloc/src/rc.rs b/library/alloc/src/rc.rs
index 0338565980c..2cc38d90ffe 100644
--- a/library/alloc/src/rc.rs
+++ b/library/alloc/src/rc.rs
@@ -1184,12 +1184,19 @@ impl<T: ?Sized> Rc<T> {
     /// Constructs an `Rc<T>` from a raw pointer.
     ///
     /// The raw pointer must have been previously returned by a call to
-    /// [`Rc<U>::into_raw`][into_raw] where `U` must have the same size
-    /// and alignment as `T`. This is trivially true if `U` is `T`.
-    /// Note that if `U` is not `T` but has the same size and alignment, this is
-    /// basically like transmuting references of different types. See
-    /// [`mem::transmute`][transmute] for more information on what
-    /// restrictions apply in this case.
+    /// [`Rc<U>::into_raw`][into_raw] with the following requirements:
+    ///
+    /// * If `U` is sized, it must have the same size and alignment as `T`. This
+    ///   is trivially true if `U` is `T`.
+    /// * If `U` is unsized, its data pointer must have the same size and
+    ///   alignment as `T`. This is trivially true if `Rc<U>` was constructed
+    ///   through `Rc<T>` and then converted to `Rc<U>` through an [unsized
+    ///   coercion].
+    ///
+    /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
+    /// and alignment, this is basically like transmuting references of
+    /// different types. See [`mem::transmute`][transmute] for more information
+    /// on what restrictions apply in this case.
     ///
     /// The raw pointer must point to a block of memory allocated by the global allocator
     ///
@@ -1201,6 +1208,7 @@ impl<T: ?Sized> Rc<T> {
     ///
     /// [into_raw]: Rc::into_raw
     /// [transmute]: core::mem::transmute
+    /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
     ///
     /// # Examples
     ///
@@ -1220,6 +1228,20 @@ impl<T: ?Sized> Rc<T> {
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
     /// ```
+    ///
+    /// Convert a slice back into its original array:
+    ///
+    /// ```
+    /// use std::rc::Rc;
+    ///
+    /// let x: Rc<[u32]> = Rc::new([1, 2, 3]);
+    /// let x_ptr: *const [u32] = Rc::into_raw(x);
+    ///
+    /// unsafe {
+    ///     let x: Rc<[u32; 3]> = Rc::from_raw(x_ptr.cast::<[u32; 3]>());
+    ///     assert_eq!(&*x, &[1, 2, 3]);
+    /// }
+    /// ```
     #[inline]
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub unsafe fn from_raw(ptr: *const T) -> Self {
@@ -1344,13 +1366,20 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
 
     /// Constructs an `Rc<T, A>` from a raw pointer in the provided allocator.
     ///
-    /// The raw pointer must have been previously returned by a call to
-    /// [`Rc<U, A>::into_raw`][into_raw] where `U` must have the same size
-    /// and alignment as `T`. This is trivially true if `U` is `T`.
-    /// Note that if `U` is not `T` but has the same size and alignment, this is
-    /// basically like transmuting references of different types. See
-    /// [`mem::transmute`] for more information on what
-    /// restrictions apply in this case.
+    /// The raw pointer must have been previously returned by a call to [`Rc<U,
+    /// A>::into_raw`][into_raw] with the following requirements:
+    ///
+    /// * If `U` is sized, it must have the same size and alignment as `T`. This
+    ///   is trivially true if `U` is `T`.
+    /// * If `U` is unsized, its data pointer must have the same size and
+    ///   alignment as `T`. This is trivially true if `Rc<U>` was constructed
+    ///   through `Rc<T>` and then converted to `Rc<U>` through an [unsized
+    ///   coercion].
+    ///
+    /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
+    /// and alignment, this is basically like transmuting references of
+    /// different types. See [`mem::transmute`][transmute] for more information
+    /// on what restrictions apply in this case.
     ///
     /// The raw pointer must point to a block of memory allocated by `alloc`
     ///
@@ -1361,6 +1390,8 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
     /// even if the returned `Rc<T>` is never accessed.
     ///
     /// [into_raw]: Rc::into_raw
+    /// [transmute]: core::mem::transmute
+    /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
     ///
     /// # Examples
     ///
@@ -1383,6 +1414,23 @@ impl<T: ?Sized, A: Allocator> Rc<T, A> {
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
     /// ```
+    ///
+    /// Convert a slice back into its original array:
+    ///
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::rc::Rc;
+    /// use std::alloc::System;
+    ///
+    /// let x: Rc<[u32], _> = Rc::new_in([1, 2, 3], System);
+    /// let x_ptr: *const [u32] = Rc::into_raw(x);
+    ///
+    /// unsafe {
+    ///     let x: Rc<[u32; 3], _> = Rc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);
+    ///     assert_eq!(&*x, &[1, 2, 3]);
+    /// }
+    /// ```
     #[unstable(feature = "allocator_api", issue = "32838")]
     pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {
         let offset = unsafe { data_offset(ptr) };
diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs
index e16574f3d80..e1211da4c61 100644
--- a/library/alloc/src/sync.rs
+++ b/library/alloc/src/sync.rs
@@ -1333,12 +1333,19 @@ impl<T: ?Sized> Arc<T> {
     /// Constructs an `Arc<T>` from a raw pointer.
     ///
     /// The raw pointer must have been previously returned by a call to
-    /// [`Arc<U>::into_raw`][into_raw] where `U` must have the same size and
-    /// alignment as `T`. This is trivially true if `U` is `T`.
-    /// Note that if `U` is not `T` but has the same size and alignment, this is
-    /// basically like transmuting references of different types. See
-    /// [`mem::transmute`][transmute] for more information on what
-    /// restrictions apply in this case.
+    /// [`Arc<U>::into_raw`][into_raw] with the following requirements:
+    ///
+    /// * If `U` is sized, it must have the same size and alignment as `T`. This
+    ///   is trivially true if `U` is `T`.
+    /// * If `U` is unsized, its data pointer must have the same size and
+    ///   alignment as `T`. This is trivially true if `Arc<U>` was constructed
+    ///   through `Arc<T>` and then converted to `Arc<U>` through an [unsized
+    ///   coercion].
+    ///
+    /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
+    /// and alignment, this is basically like transmuting references of
+    /// different types. See [`mem::transmute`][transmute] for more information
+    /// on what restrictions apply in this case.
     ///
     /// The user of `from_raw` has to make sure a specific value of `T` is only
     /// dropped once.
@@ -1348,6 +1355,7 @@ impl<T: ?Sized> Arc<T> {
     ///
     /// [into_raw]: Arc::into_raw
     /// [transmute]: core::mem::transmute
+    /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
     ///
     /// # Examples
     ///
@@ -1367,6 +1375,20 @@ impl<T: ?Sized> Arc<T> {
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
     /// ```
+    ///
+    /// Convert a slice back into its original array:
+    ///
+    /// ```
+    /// use std::sync::Arc;
+    ///
+    /// let x: Arc<[u32]> = Arc::new([1, 2, 3]);
+    /// let x_ptr: *const [u32] = Arc::into_raw(x);
+    ///
+    /// unsafe {
+    ///     let x: Arc<[u32; 3]> = Arc::from_raw(x_ptr.cast::<[u32; 3]>());
+    ///     assert_eq!(&*x, &[1, 2, 3]);
+    /// }
+    /// ```
     #[inline]
     #[stable(feature = "rc_raw", since = "1.17.0")]
     pub unsafe fn from_raw(ptr: *const T) -> Self {
@@ -1496,13 +1518,20 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
 
     /// Constructs an `Arc<T, A>` from a raw pointer.
     ///
-    /// The raw pointer must have been previously returned by a call to
-    /// [`Arc<U, A>::into_raw`][into_raw] where `U` must have the same size and
-    /// alignment as `T`. This is trivially true if `U` is `T`.
-    /// Note that if `U` is not `T` but has the same size and alignment, this is
-    /// basically like transmuting references of different types. See
-    /// [`mem::transmute`] for more information on what
-    /// restrictions apply in this case.
+    /// The raw pointer must have been previously returned by a call to [`Arc<U,
+    /// A>::into_raw`][into_raw] with the following requirements:
+    ///
+    /// * If `U` is sized, it must have the same size and alignment as `T`. This
+    ///   is trivially true if `U` is `T`.
+    /// * If `U` is unsized, its data pointer must have the same size and
+    ///   alignment as `T`. This is trivially true if `Arc<U>` was constructed
+    ///   through `Arc<T>` and then converted to `Arc<U>` through an [unsized
+    ///   coercion].
+    ///
+    /// Note that if `U` or `U`'s data pointer is not `T` but has the same size
+    /// and alignment, this is basically like transmuting references of
+    /// different types. See [`mem::transmute`][transmute] for more information
+    /// on what restrictions apply in this case.
     ///
     /// The raw pointer must point to a block of memory allocated by `alloc`
     ///
@@ -1513,6 +1542,8 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     /// even if the returned `Arc<T>` is never accessed.
     ///
     /// [into_raw]: Arc::into_raw
+    /// [transmute]: core::mem::transmute
+    /// [unsized coercion]: https://doc.rust-lang.org/reference/type-coercions.html#unsized-coercions
     ///
     /// # Examples
     ///
@@ -1535,6 +1566,23 @@ impl<T: ?Sized, A: Allocator> Arc<T, A> {
     ///
     /// // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
     /// ```
+    ///
+    /// Convert a slice back into its original array:
+    ///
+    /// ```
+    /// #![feature(allocator_api)]
+    ///
+    /// use std::sync::Arc;
+    /// use std::alloc::System;
+    ///
+    /// let x: Arc<[u32], _> = Arc::new_in([1, 2, 3], System);
+    /// let x_ptr: *const [u32] = Arc::into_raw(x);
+    ///
+    /// unsafe {
+    ///     let x: Arc<[u32; 3], _> = Arc::from_raw_in(x_ptr.cast::<[u32; 3]>(), System);
+    ///     assert_eq!(&*x, &[1, 2, 3]);
+    /// }
+    /// ```
     #[inline]
     #[unstable(feature = "allocator_api", issue = "32838")]
     pub unsafe fn from_raw_in(ptr: *const T, alloc: A) -> Self {
diff --git a/library/core/src/str/validations.rs b/library/core/src/str/validations.rs
index 2acef432f20..a11d7fee8af 100644
--- a/library/core/src/str/validations.rs
+++ b/library/core/src/str/validations.rs
@@ -161,7 +161,7 @@ pub(super) const fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
             //        first  E0 A0 80     last EF BF BF
             //   excluding surrogates codepoints  \u{d800} to  \u{dfff}
             //               ED A0 80 to       ED BF BF
-            // 4-byte encoding is for codepoints \u{1000}0 to \u{10ff}ff
+            // 4-byte encoding is for codepoints \u{10000} to \u{10ffff}
             //        first  F0 90 80 80  last F4 8F BF BF
             //
             // Use the UTF-8 syntax from the RFC
diff --git a/library/core/src/task/wake.rs b/library/core/src/task/wake.rs
index b9895f7edea..8fc942dedc9 100644
--- a/library/core/src/task/wake.rs
+++ b/library/core/src/task/wake.rs
@@ -441,7 +441,9 @@ impl Waker {
     #[must_use]
     #[stable(feature = "futures_api", since = "1.36.0")]
     pub fn will_wake(&self, other: &Waker) -> bool {
-        self.waker == other.waker
+        let RawWaker { data: a_data, vtable: a_vtable } = self.waker;
+        let RawWaker { data: b_data, vtable: b_vtable } = other.waker;
+        a_data == b_data && ptr::eq(a_vtable, b_vtable)
     }
 
     /// Creates a new `Waker` from [`RawWaker`].
diff --git a/library/core/src/unicode/unicode_data.rs b/library/core/src/unicode/unicode_data.rs
index b25e9df2868..dd2ad9a58f6 100644
--- a/library/core/src/unicode/unicode_data.rs
+++ b/library/core/src/unicode/unicode_data.rs
@@ -99,21 +99,21 @@ fn skip_search<const SOR: usize, const OFFSETS: usize>(
     offset_idx % 2 == 1
 }
 
-pub const UNICODE_VERSION: (u8, u8, u8) = (15, 0, 0);
+pub const UNICODE_VERSION: (u8, u8, u8) = (15, 1, 0);
 
 #[rustfmt::skip]
 pub mod alphabetic {
-    static SHORT_OFFSET_RUNS: [u32; 53] = [
+    static SHORT_OFFSET_RUNS: [u32; 54] = [
         706, 33559113, 872420973, 952114966, 1161831606, 1310731264, 1314926597, 1394619392,
         1444957632, 1447077005, 1451271693, 1459672996, 1648425216, 1658911342, 1661009214,
         1707147904, 1793132343, 1887506048, 2040601600, 2392923872, 2481005466, 2504077200,
         2514564144, 2520859648, 2527151687, 2529257472, 2531355193, 2533453376, 2564917240,
         2596375766, 2600579056, 2606870819, 2621551356, 2642525184, 2644628480, 2665600678,
         2743197440, 2791432848, 2841765072, 2850154464, 2854350336, 2887905584, 3026321408,
-        3038947040, 3041048378, 3045248674, 3053644769, 3057842176, 3059939870, 3062038528,
-        3064140619, 3066241968, 3071550384,
+        3038947040, 3041048378, 3045248674, 3053644769, 3057839710, 3062036480, 3064134174,
+        3066232832, 3068334923, 3070436272, 3075744688,
     ];
-    static OFFSETS: [u8; 1465] = [
+    static OFFSETS: [u8; 1467] = [
         65, 26, 6, 26, 47, 1, 10, 1, 4, 1, 5, 23, 1, 31, 1, 0, 4, 12, 14, 5, 7, 1, 1, 1, 86, 1, 42,
         5, 1, 2, 2, 4, 1, 1, 6, 1, 1, 3, 1, 1, 1, 20, 1, 83, 1, 139, 8, 166, 1, 38, 2, 1, 6, 41, 39,
         14, 1, 1, 1, 2, 1, 2, 1, 1, 8, 27, 4, 4, 29, 11, 5, 56, 1, 7, 14, 102, 1, 8, 4, 8, 4, 3, 10,
@@ -167,7 +167,7 @@ pub mod alphabetic {
         1, 2, 1, 15, 1, 197, 59, 68, 3, 1, 3, 1, 0, 4, 1, 27, 1, 2, 1, 1, 2, 1, 1, 10, 1, 4, 1, 1,
         1, 1, 6, 1, 4, 1, 1, 1, 1, 1, 1, 3, 1, 2, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 2,
         4, 1, 7, 1, 4, 1, 4, 1, 1, 1, 10, 1, 17, 5, 3, 1, 5, 1, 17, 0, 26, 6, 26, 6, 26, 0, 0, 32,
-        0, 6, 222, 2, 0, 14, 0, 0, 0, 0, 0, 5, 0, 0,
+        0, 6, 222, 2, 0, 14, 0, 15, 0, 0, 0, 0, 0, 5, 0, 0,
     ];
     pub fn lookup(c: char) -> bool {
         super::skip_search(
diff --git a/library/proc_macro/src/bridge/mod.rs b/library/proc_macro/src/bridge/mod.rs
index 55e24b6491c..9b337f23867 100644
--- a/library/proc_macro/src/bridge/mod.rs
+++ b/library/proc_macro/src/bridge/mod.rs
@@ -337,7 +337,11 @@ pub enum LitKind {
     ByteStrRaw(u8),
     CStr,
     CStrRaw(u8),
-    Err,
+    // This should have an `ErrorGuaranteed`, except that type isn't available
+    // in this crate. (Imagine it is there.) Hence the `WithGuar` suffix. Must
+    // only be constructed in `LitKind::from_internal`, where an
+    // `ErrorGuaranteed` is available.
+    ErrWithGuar,
 }
 
 rpc_encode_decode!(
@@ -352,7 +356,7 @@ rpc_encode_decode!(
         ByteStrRaw(n),
         CStr,
         CStrRaw(n),
-        Err,
+        ErrWithGuar,
     }
 );
 
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 90b76cbc26e..7c492941713 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -1451,7 +1451,7 @@ impl Literal {
                 f(&["cr", hashes, "\"", symbol, "\"", hashes, suffix])
             }
 
-            bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::Err => {
+            bridge::LitKind::Integer | bridge::LitKind::Float | bridge::LitKind::ErrWithGuar => {
                 f(&[symbol, suffix])
             }
         })
diff --git a/library/std/src/sys/pal/unix/thread.rs b/library/std/src/sys/pal/unix/thread.rs
index 7e4a01a5ecd..ba8d31c23a5 100644
--- a/library/std/src/sys/pal/unix/thread.rs
+++ b/library/std/src/sys/pal/unix/thread.rs
@@ -847,11 +847,31 @@ pub mod guard {
             let stackptr = get_stack_start_aligned()?;
             let guardaddr = stackptr.addr();
             // Technically the number of guard pages is tunable and controlled
-            // by the security.bsd.stack_guard_page sysctl, but there are
-            // few reasons to change it from the default. The default value has
-            // been 1 ever since FreeBSD 11.1 and 10.4.
-            const GUARD_PAGES: usize = 1;
-            let guard = guardaddr..guardaddr + GUARD_PAGES * page_size;
+            // by the security.bsd.stack_guard_page sysctl.
+            // By default it is 1, checking once is enough since it is
+            // a boot time config value.
+            static LOCK: crate::sync::OnceLock<usize> = crate::sync::OnceLock::new();
+            let guard = guardaddr
+                ..guardaddr
+                    + *LOCK.get_or_init(|| {
+                        use crate::sys::weak::dlsym;
+                        dlsym!(fn sysctlbyname(*const libc::c_char, *mut libc::c_void, *mut libc::size_t, *const libc::c_void, libc::size_t) -> libc::c_int);
+                        let mut guard: usize = 0;
+                        let mut size = crate::mem::size_of_val(&guard);
+                        let oid = crate::ffi::CStr::from_bytes_with_nul(
+                            b"security.bsd.stack_guard_page\0",
+                        )
+                        .unwrap();
+                        match sysctlbyname.get() {
+                            Some(fcn) => {
+                                if fcn(oid.as_ptr(), &mut guard as *mut _ as *mut _, &mut size as *mut _ as *mut _, crate::ptr::null_mut(), 0) == 0 {
+                                    return guard;
+                                }
+                                return 1;
+                            },
+                            _ => { return 1; }
+                        }
+                    }) * page_size;
             Some(guard)
         } else if cfg!(target_os = "openbsd") {
             // OpenBSD stack already includes a guard page, and stack is
diff --git a/src/librustdoc/doctest.rs b/src/librustdoc/doctest.rs
index f2e083de0ec..f9d4d1af114 100644
--- a/src/librustdoc/doctest.rs
+++ b/src/librustdoc/doctest.rs
@@ -40,6 +40,9 @@ use crate::lint::init_lints;
 pub(crate) struct GlobalTestOptions {
     /// Whether to disable the default `extern crate my_crate;` when creating doctests.
     pub(crate) no_crate_inject: bool,
+    /// Whether inserting extra indent spaces in code block,
+    /// default is `false`, only `true` for generating code link of Rust playground
+    pub(crate) insert_indent_space: bool,
     /// Additional crate-level attributes to add to doctests.
     pub(crate) attrs: Vec<String>,
 }
@@ -221,7 +224,8 @@ pub(crate) fn run_tests(
 fn scrape_test_config(attrs: &[ast::Attribute]) -> GlobalTestOptions {
     use rustc_ast_pretty::pprust;
 
-    let mut opts = GlobalTestOptions { no_crate_inject: false, attrs: Vec::new() };
+    let mut opts =
+        GlobalTestOptions { no_crate_inject: false, attrs: Vec::new(), insert_indent_space: false };
 
     let test_attrs: Vec<_> = attrs
         .iter()
@@ -725,7 +729,17 @@ pub(crate) fn make_test(
         // /// ``` <- end of the inner main
         line_offset += 1;
 
-        prog.extend([&main_pre, everything_else, &main_post].iter().cloned());
+        // add extra 4 spaces for each line to offset the code block
+        let content = if opts.insert_indent_space {
+            everything_else
+                .lines()
+                .map(|line| format!("    {}", line))
+                .collect::<Vec<String>>()
+                .join("\n")
+        } else {
+            everything_else.to_string()
+        };
+        prog.extend([&main_pre, content.as_str(), &main_post].iter().cloned());
     }
 
     debug!("final doctest:\n{prog}");
diff --git a/src/librustdoc/doctest/tests.rs b/src/librustdoc/doctest/tests.rs
index a30fe28f94f..9629acb31eb 100644
--- a/src/librustdoc/doctest/tests.rs
+++ b/src/librustdoc/doctest/tests.rs
@@ -53,7 +53,8 @@ assert_eq!(2+2, 4);
 fn make_test_no_crate_inject() {
     // Even if you do use the crate within the test, setting `opts.no_crate_inject` will skip
     // adding it anyway.
-    let opts = GlobalTestOptions { no_crate_inject: true, attrs: vec![] };
+    let opts =
+        GlobalTestOptions { no_crate_inject: true, attrs: vec![], insert_indent_space: false };
     let input = "use asdf::qwop;
 assert_eq!(2+2, 4);";
     let expected = "#![allow(unused)]
@@ -302,3 +303,44 @@ assert_eq!(2+2, 4);
         make_test(input, None, false, &opts, DEFAULT_EDITION, Some("_some_unique_name"));
     assert_eq!((output, len), (expected, 2));
 }
+
+#[test]
+fn make_test_insert_extra_space() {
+    // will insert indent spaces in the code block if `insert_indent_space` is true
+    let opts =
+        GlobalTestOptions { no_crate_inject: false, attrs: vec![], insert_indent_space: true };
+    let input = "use std::*;
+assert_eq!(2+2, 4);
+eprintln!(\"hello anan\");
+";
+    let expected = "#![allow(unused)]
+fn main() {
+    use std::*;
+    assert_eq!(2+2, 4);
+    eprintln!(\"hello anan\");
+}"
+    .to_string();
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
+    assert_eq!((output, len), (expected, 2));
+}
+
+#[test]
+fn make_test_insert_extra_space_fn_main() {
+    // if input already has a fn main, it should insert a space before it
+    let opts =
+        GlobalTestOptions { no_crate_inject: false, attrs: vec![], insert_indent_space: true };
+    let input = "use std::*;
+fn main() {
+    assert_eq!(2+2, 4);
+    eprintln!(\"hello anan\");
+}";
+    let expected = "#![allow(unused)]
+use std::*;
+fn main() {
+    assert_eq!(2+2, 4);
+    eprintln!(\"hello anan\");
+}"
+    .to_string();
+    let (output, len, _) = make_test(input, None, false, &opts, DEFAULT_EDITION, None);
+    assert_eq!((output, len), (expected, 1));
+}
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index ee5891c12fc..21f682d15b9 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -45,6 +45,7 @@ use std::str::{self, CharIndices};
 
 use crate::clean::RenderedLink;
 use crate::doctest;
+use crate::doctest::GlobalTestOptions;
 use crate::html::escape::Escape;
 use crate::html::format::Buffer;
 use crate::html::highlight;
@@ -302,8 +303,10 @@ impl<'a, I: Iterator<Item = Event<'a>>> Iterator for CodeBlocks<'_, 'a, I> {
                 .intersperse("\n".into())
                 .collect::<String>();
             let krate = krate.as_ref().map(|s| s.as_str());
-            let (test, _, _) =
-                doctest::make_test(&test, krate, false, &Default::default(), edition, None);
+
+            let mut opts: GlobalTestOptions = Default::default();
+            opts.insert_indent_space = true;
+            let (test, _, _) = doctest::make_test(&test, krate, false, &opts, edition, None);
             let channel = if test.contains("#![feature(") { "&amp;version=nightly" } else { "" };
 
             let test_escaped = small_url_encode(test);
diff --git a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
index 6595658b769..b8f7d966820 100644
--- a/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
+++ b/src/tools/clippy/clippy_lints/src/matches/match_same_arms.rs
@@ -295,7 +295,8 @@ impl<'a> NormalizedPat<'a> {
                     LitKind::Char(val) => Self::LitInt(val.into()),
                     LitKind::Int(val, _) => Self::LitInt(val.get()),
                     LitKind::Bool(val) => Self::LitBool(val),
-                    LitKind::Float(..) | LitKind::Err => Self::Wild,
+                    LitKind::Float(..) => Self::Wild,
+                    LitKind::Err(guar) => Self::Err(guar),
                 },
                 _ => Self::Wild,
             },
diff --git a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
index c8352c05265..079e6500e3c 100644
--- a/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
+++ b/src/tools/clippy/clippy_lints/src/redundant_type_annotations.rs
@@ -200,7 +200,7 @@ impl LateLintPass<'_> for RedundantTypeAnnotations {
                                 span_lint(cx, REDUNDANT_TYPE_ANNOTATIONS, local.span, "redundant type annotation");
                             }
                         },
-                        LitKind::Err => (),
+                        LitKind::Err(_) => (),
                         LitKind::ByteStr(..) => {
                             // We only lint if the type annotation is an array type (e.g. &[u8; 4]).
                             // If instead it is a slice (e.g. &[u8]) it may not be redundant, so we
diff --git a/src/tools/clippy/clippy_lints/src/utils/author.rs b/src/tools/clippy/clippy_lints/src/utils/author.rs
index 29c67341a46..a0a6382046d 100644
--- a/src/tools/clippy/clippy_lints/src/utils/author.rs
+++ b/src/tools/clippy/clippy_lints/src/utils/author.rs
@@ -279,7 +279,7 @@ impl<'a, 'tcx> PrintVisitor<'a, 'tcx> {
         match lit.value.node {
             LitKind::Bool(val) => kind!("Bool({val:?})"),
             LitKind::Char(c) => kind!("Char({c:?})"),
-            LitKind::Err => kind!("Err"),
+            LitKind::Err(_) => kind!("Err"),
             LitKind::Byte(b) => kind!("Byte({b})"),
             LitKind::Int(i, suffix) => {
                 let int_ty = match suffix {
diff --git a/src/tools/clippy/clippy_utils/src/ast_utils.rs b/src/tools/clippy/clippy_utils/src/ast_utils.rs
index adc35bd82ae..0467a8a6570 100644
--- a/src/tools/clippy/clippy_utils/src/ast_utils.rs
+++ b/src/tools/clippy/clippy_utils/src/ast_utils.rs
@@ -690,7 +690,7 @@ pub fn eq_ty(l: &Ty, r: &Ty) -> bool {
     match (&l.kind, &r.kind) {
         (Paren(l), _) => eq_ty(l, r),
         (_, Paren(r)) => eq_ty(l, r),
-        (Never, Never) | (Infer, Infer) | (ImplicitSelf, ImplicitSelf) | (Err, Err) | (CVarArgs, CVarArgs) => true,
+        (Never, Never) | (Infer, Infer) | (ImplicitSelf, ImplicitSelf) | (Err(_), Err(_)) | (CVarArgs, CVarArgs) => true,
         (Slice(l), Slice(r)) => eq_ty(l, r),
         (Array(le, ls), Array(re, rs)) => eq_ty(le, re) && eq_expr(&ls.value, &rs.value),
         (Ptr(l), Ptr(r)) => l.mutbl == r.mutbl && eq_ty(&l.ty, &r.ty),
diff --git a/src/tools/clippy/clippy_utils/src/consts.rs b/src/tools/clippy/clippy_utils/src/consts.rs
index 61b38391d9e..79c691992a8 100644
--- a/src/tools/clippy/clippy_utils/src/consts.rs
+++ b/src/tools/clippy/clippy_utils/src/consts.rs
@@ -286,7 +286,7 @@ pub fn lit_to_mir_constant<'tcx>(lit: &LitKind, ty: Option<Ty<'tcx>>) -> Constan
             _ => bug!(),
         },
         LitKind::Bool(b) => Constant::Bool(b),
-        LitKind::Err => Constant::Err,
+        LitKind::Err(_) => Constant::Err,
     }
 }
 
diff --git a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
index f799a4698b9..b178fb7512c 100644
--- a/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
+++ b/src/tools/clippy/tests/ui/match_str_case_mismatch.stderr
@@ -17,7 +17,7 @@ error: this `match` arm has a differing case than its expression
 LL |         "~!@#$%^&*()-_=+Foo" => {},
    |         ^^^^^^^^^^^^^^^^^^^^
    |
-help: consider changing the case of this arm to respect `to_ascii_lowercase`
+help: consider changing the case of this arm to respect `to_ascii_lowercase` (notice the capitalization difference)
    |
 LL |         "~!@#$%^&*()-_=+foo" => {},
    |         ~~~~~~~~~~~~~~~~~~~~
diff --git a/src/tools/miri/src/shims/intrinsics/mod.rs b/src/tools/miri/src/shims/intrinsics/mod.rs
index e34fb118f72..df2761bfaf4 100644
--- a/src/tools/miri/src/shims/intrinsics/mod.rs
+++ b/src/tools/miri/src/shims/intrinsics/mod.rs
@@ -108,12 +108,12 @@ pub trait EvalContextExt<'mir, 'tcx: 'mir>: crate::MiriInterpCxExt<'mir, 'tcx> {
             "volatile_load" => {
                 let [place] = check_arg_count(args)?;
                 let place = this.deref_pointer(place)?;
-                this.copy_op(&place, dest, /*allow_transmute*/ false)?;
+                this.copy_op(&place, dest)?;
             }
             "volatile_store" => {
                 let [place, dest] = check_arg_count(args)?;
                 let place = this.deref_pointer(place)?;
-                this.copy_op(dest, &place, /*allow_transmute*/ false)?;
+                this.copy_op(dest, &place)?;
             }
 
             "write_bytes" | "volatile_set_memory" => {
diff --git a/src/tools/miri/src/shims/x86/mod.rs b/src/tools/miri/src/shims/x86/mod.rs
index 1aaf820f460..b24ea8aec84 100644
--- a/src/tools/miri/src/shims/x86/mod.rs
+++ b/src/tools/miri/src/shims/x86/mod.rs
@@ -299,7 +299,6 @@ fn bin_op_simd_float_first<'tcx, F: rustc_apfloat::Float>(
         this.copy_op(
             &this.project_index(&left, i)?,
             &this.project_index(&dest, i)?,
-            /*allow_transmute*/ false,
         )?;
     }
 
@@ -424,7 +423,6 @@ fn unary_op_ss<'tcx>(
         this.copy_op(
             &this.project_index(&op, i)?,
             &this.project_index(&dest, i)?,
-            /*allow_transmute*/ false,
         )?;
     }
 
@@ -484,7 +482,6 @@ fn round_first<'tcx, F: rustc_apfloat::Float>(
         this.copy_op(
             &this.project_index(&left, i)?,
             &this.project_index(&dest, i)?,
-            /*allow_transmute*/ false,
         )?;
     }
 
diff --git a/src/tools/miri/src/shims/x86/sse.rs b/src/tools/miri/src/shims/x86/sse.rs
index 1e9afc1e9e0..9fb947cb2a3 100644
--- a/src/tools/miri/src/shims/x86/sse.rs
+++ b/src/tools/miri/src/shims/x86/sse.rs
@@ -211,7 +211,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.copy_op(
                         &this.project_index(&left, i)?,
                         &this.project_index(&dest, i)?,
-                        /*allow_transmute*/ false,
                     )?;
                 }
             }
diff --git a/src/tools/miri/src/shims/x86/sse2.rs b/src/tools/miri/src/shims/x86/sse2.rs
index 49bf7547ab0..e5c8267320a 100644
--- a/src/tools/miri/src/shims/x86/sse2.rs
+++ b/src/tools/miri/src/shims/x86/sse2.rs
@@ -443,7 +443,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.copy_op(
                         &this.project_index(&op, i)?,
                         &this.project_index(&dest, i)?,
-                        /*allow_transmute*/ false,
                     )?;
                 }
             }
@@ -584,7 +583,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                     this.copy_op(
                         &this.project_index(&left, i)?,
                         &this.project_index(&dest, i)?,
-                        /*allow_transmute*/ false,
                     )?;
                 }
             }
diff --git a/src/tools/miri/src/shims/x86/sse41.rs b/src/tools/miri/src/shims/x86/sse41.rs
index 67bb63f0a3d..2abd10fa7a7 100644
--- a/src/tools/miri/src/shims/x86/sse41.rs
+++ b/src/tools/miri/src/shims/x86/sse41.rs
@@ -60,7 +60,6 @@ pub(super) trait EvalContextExt<'mir, 'tcx: 'mir>:
                         this.copy_op(
                             &this.project_index(&left, i)?,
                             &dest,
-                            /*allow_transmute*/ false,
                         )?;
                     }
                 }
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/rust_analyzer_span.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/rust_analyzer_span.rs
index c7c7bea9941..8a9d52a37a2 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/rust_analyzer_span.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/rust_analyzer_span.rs
@@ -72,7 +72,7 @@ impl server::FreeFunctions for RaSpanServer {
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
         // FIXME: keep track of LitKind and Suffix
         Ok(bridge::Literal {
-            kind: bridge::LitKind::Err,
+            kind: bridge::LitKind::Integer, // dummy
             symbol: Symbol::intern(self.interner, s),
             suffix: None,
             span: self.call_site,
@@ -202,7 +202,7 @@ impl server::TokenStream for RaSpanServer {
                 tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
                     bridge::TokenTree::Literal(bridge::Literal {
                         // FIXME: handle literal kinds
-                        kind: bridge::LitKind::Err,
+                        kind: bridge::LitKind::Integer, // dummy
                         symbol: Symbol::intern(self.interner, &lit.text),
                         // FIXME: handle suffixes
                         suffix: None,
diff --git a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_id.rs b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_id.rs
index edbdc67b482..15a9e0deae4 100644
--- a/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_id.rs
+++ b/src/tools/rust-analyzer/crates/proc-macro-srv/src/server/token_id.rs
@@ -64,7 +64,7 @@ impl server::FreeFunctions for TokenIdServer {
     ) -> Result<bridge::Literal<Self::Span, Self::Symbol>, ()> {
         // FIXME: keep track of LitKind and Suffix
         Ok(bridge::Literal {
-            kind: bridge::LitKind::Err,
+            kind: bridge::LitKind::Integer, // dummy
             symbol: Symbol::intern(self.interner, s),
             suffix: None,
             span: self.call_site,
@@ -187,7 +187,7 @@ impl server::TokenStream for TokenIdServer {
                 tt::TokenTree::Leaf(tt::Leaf::Literal(lit)) => {
                     bridge::TokenTree::Literal(bridge::Literal {
                         // FIXME: handle literal kinds
-                        kind: bridge::LitKind::Err,
+                        kind: bridge::LitKind::Integer, // dummy
                         symbol: Symbol::intern(self.interner, &lit.text),
                         // FIXME: handle suffixes
                         suffix: None,
diff --git a/src/tools/rustfmt/src/types.rs b/src/tools/rustfmt/src/types.rs
index 4cd8e6a703e..7f220a456a8 100644
--- a/src/tools/rustfmt/src/types.rs
+++ b/src/tools/rustfmt/src/types.rs
@@ -859,7 +859,7 @@ impl Rewrite for ast::Ty {
                 })
             }
             ast::TyKind::CVarArgs => Some("...".to_owned()),
-            ast::TyKind::Err => Some(context.snippet(self.span).to_owned()),
+            ast::TyKind::Dummy | ast::TyKind::Err(_) => Some(context.snippet(self.span).to_owned()),
             ast::TyKind::Typeof(ref anon_const) => rewrite_call(
                 context,
                 "typeof",
diff --git a/tests/rustdoc/playground-arg.rs b/tests/rustdoc/playground-arg.rs
index 2542ed657c1..1d7085064e5 100644
--- a/tests/rustdoc/playground-arg.rs
+++ b/tests/rustdoc/playground-arg.rs
@@ -10,4 +10,4 @@
 pub fn dummy() {}
 
 // ensure that `extern crate foo;` was inserted into code snips automatically:
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0Ause+foo::dummy;%0Adummy();%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://example.com/?code=%23!%5Ballow(unused)%5D%0A%23%5Ballow(unused_extern_crates)%5D%0Aextern+crate+r%23foo;%0Afn+main()+%7B%0A++++use+foo::dummy;%0A++++dummy();%0A%7D&edition=2015"]' "Run"
diff --git a/tests/rustdoc/playground.rs b/tests/rustdoc/playground.rs
index 5c7fa33efc5..a2fc9eb7387 100644
--- a/tests/rustdoc/playground.rs
+++ b/tests/rustdoc/playground.rs
@@ -22,6 +22,6 @@
 //! }
 //! ```
 
-// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0Aprintln!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
+// @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
 // @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&edition=2015"]' "Run"
 // @matches foo/index.html '//a[@class="test-arrow"][@href="https://www.example.com/?code=%23!%5Ballow(unused)%5D%0A%23!%5Bfeature(something)%5D%0A%0Afn+main()+%7B%0A++++println!(%22Hello,+world!%22);%0A%7D&version=nightly&edition=2015"]' "Run"
diff --git a/tests/ui/asm/x86_64/evex512-implicit-feature.rs b/tests/ui/asm/x86_64/evex512-implicit-feature.rs
new file mode 100644
index 00000000000..a15060857ec
--- /dev/null
+++ b/tests/ui/asm/x86_64/evex512-implicit-feature.rs
@@ -0,0 +1,15 @@
+// build-pass
+// only-x86_64
+// compile-flags: --crate-type=lib -C target-cpu=skylake
+
+#![feature(avx512_target_feature)]
+#![feature(stdarch_x86_avx512)]
+
+use std::arch::x86_64::*;
+
+#[target_feature(enable = "avx512f")]
+#[no_mangle]
+pub unsafe fn test(res: *mut f64, p: *const f64) {
+    let arg = _mm512_load_pd(p);
+    _mm512_store_pd(res, _mm512_fmaddsub_pd(arg, arg, arg));
+}
diff --git a/tests/ui/async-await/async-closures/not-fn.rs b/tests/ui/async-await/async-closures/not-fn.rs
new file mode 100644
index 00000000000..4505e6243e9
--- /dev/null
+++ b/tests/ui/async-await/async-closures/not-fn.rs
@@ -0,0 +1,15 @@
+// edition:2021
+
+// FIXME(async_closures): This needs a better error message!
+
+#![feature(async_closure)]
+
+fn main() {
+    fn needs_fn<T>(_: impl FnMut() -> T) {}
+
+    let mut x = 1;
+    needs_fn(async || {
+        //~^ ERROR  async closure does not implement `FnMut` because it captures state from its environment
+        x += 1;
+    });
+}
diff --git a/tests/ui/async-await/async-closures/not-fn.stderr b/tests/ui/async-await/async-closures/not-fn.stderr
new file mode 100644
index 00000000000..9c40613599a
--- /dev/null
+++ b/tests/ui/async-await/async-closures/not-fn.stderr
@@ -0,0 +1,16 @@
+error: async closure does not implement `FnMut` because it captures state from its environment
+  --> $DIR/not-fn.rs:11:14
+   |
+LL |     needs_fn(async || {
+   |     -------- ^^^^^^^^
+   |     |
+   |     required by a bound introduced by this call
+   |
+note: required by a bound in `needs_fn`
+  --> $DIR/not-fn.rs:8:28
+   |
+LL |     fn needs_fn<T>(_: impl FnMut() -> T) {}
+   |                            ^^^^^^^^^^^^ required by this bound in `needs_fn`
+
+error: aborting due to 1 previous error
+
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.rs b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
index f86cee3e070..1e372deb984 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.rs
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.rs
@@ -9,8 +9,7 @@ fn main() {
 
     let mut x = 1;
     needs_async_fn(async || {
-        //~^ ERROR i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>
-        // FIXME: Should say "closure is `async FnMut` but it needs `async Fn`" or sth.
+        //~^ ERROR expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
         x += 1;
     });
 }
diff --git a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
index 4ef8484cc34..34a6b3a485a 100644
--- a/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
+++ b/tests/ui/async-await/async-closures/wrong-fn-kind.stderr
@@ -1,15 +1,17 @@
-error[E0277]: the trait bound `i16: ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not satisfied
+error[E0525]: expected a closure that implements the `async Fn` trait, but this closure only implements `async FnMut`
   --> $DIR/wrong-fn-kind.rs:11:20
    |
 LL |       needs_async_fn(async || {
-   |  _____--------------_^
+   |       -------------- -^^^^^^^
+   |       |              |
+   |  _____|______________this closure implements `async FnMut`, not `async Fn`
    | |     |
    | |     required by a bound introduced by this call
 LL | |
-LL | |         // FIXME: Should say "closure is `async FnMut` but it needs `async Fn`" or sth.
 LL | |         x += 1;
+   | |         - closure is `async FnMut` because it mutates the variable `x` here
 LL | |     });
-   | |_____^ the trait `ops::async_function::internal_implementation_detail::AsyncFnKindHelper<i8>` is not implemented for `i16`
+   | |_____- the requirement to implement `async Fn` derives from here
    |
 note: required by a bound in `needs_async_fn`
   --> $DIR/wrong-fn-kind.rs:8:31
@@ -19,4 +21,4 @@ LL |     fn needs_async_fn(_: impl async Fn()) {}
 
 error: aborting due to 1 previous error
 
-For more information about this error, try `rustc --explain E0277`.
+For more information about this error, try `rustc --explain E0525`.
diff --git a/tests/ui/const-generics/wrong-normalization.rs b/tests/ui/const-generics/wrong-normalization.rs
index f1ce317b3f7..8b2323e3d47 100644
--- a/tests/ui/const-generics/wrong-normalization.rs
+++ b/tests/ui/const-generics/wrong-normalization.rs
@@ -15,5 +15,6 @@ pub struct I8<const F: i8>;
 
 impl <I8<{i8::MIN}> as Identity>::Identity {
 //~^ ERROR no nominal type found for inherent implementation
+//~| ERROR no associated item named `MIN` found for type `i8`
     pub fn foo(&self) {}
 }
diff --git a/tests/ui/const-generics/wrong-normalization.stderr b/tests/ui/const-generics/wrong-normalization.stderr
index 2f8dfc895b2..379a5593dd6 100644
--- a/tests/ui/const-generics/wrong-normalization.stderr
+++ b/tests/ui/const-generics/wrong-normalization.stderr
@@ -6,6 +6,18 @@ LL | impl <I8<{i8::MIN}> as Identity>::Identity {
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error: aborting due to 1 previous error
+error[E0599]: no associated item named `MIN` found for type `i8` in the current scope
+  --> $DIR/wrong-normalization.rs:16:15
+   |
+LL | impl <I8<{i8::MIN}> as Identity>::Identity {
+   |               ^^^ associated item not found in `i8`
+   |
+help: you are looking for the module in `std`, not the primitive type
+   |
+LL | impl <I8<{std::i8::MIN}> as Identity>::Identity {
+   |           +++++
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0118`.
+Some errors have detailed explanations: E0118, E0599.
+For more information about an error, try `rustc --explain E0118`.
diff --git a/tests/ui/consts/recursive-zst-static.default.stderr b/tests/ui/consts/recursive-zst-static.default.stderr
index 5b4a0418b1e..7679c50c74b 100644
--- a/tests/ui/consts/recursive-zst-static.default.stderr
+++ b/tests/ui/consts/recursive-zst-static.default.stderr
@@ -1,21 +1,35 @@
-error[E0391]: cycle detected when const-evaluating + checking `FOO`
+error[E0080]: could not evaluate static initializer
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
-   |                  ^^^
+   |                  ^^^ encountered static that tried to initialize itself with itself
+
+error[E0391]: cycle detected when evaluating initializer of static `A`
+  --> $DIR/recursive-zst-static.rs:13:16
+   |
+LL | static A: () = B;
+   |                ^
    |
-   = note: ...which immediately requires const-evaluating + checking `FOO` again
+note: ...which requires evaluating initializer of static `B`...
+  --> $DIR/recursive-zst-static.rs:14:16
+   |
+LL | static B: () = A;
+   |                ^
+   = note: ...which again requires evaluating initializer of static `A`, completing the cycle
 note: cycle used when linting top-level module
   --> $DIR/recursive-zst-static.rs:10:1
    |
 LL | / static FOO: () = FOO;
 LL | |
-LL | | fn main() {
+LL | |
+LL | | static A: () = B;
+...  |
 LL | |     FOO
 LL | | }
    | |_^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0391`.
+Some errors have detailed explanations: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/recursive-zst-static.rs b/tests/ui/consts/recursive-zst-static.rs
index 4e61634b349..9311490020d 100644
--- a/tests/ui/consts/recursive-zst-static.rs
+++ b/tests/ui/consts/recursive-zst-static.rs
@@ -7,7 +7,11 @@
 // can depend on this fact and will thus do unsound things when it is violated.
 // See https://github.com/rust-lang/rust/issues/71078 for more details.
 
-static FOO: () = FOO; //~ cycle detected when const-evaluating + checking `FOO`
+static FOO: () = FOO;
+//~^ ERROR could not evaluate static initializer
+
+static A: () = B; //~ cycle detected when evaluating initializer of static `A`
+static B: () = A;
 
 fn main() {
     FOO
diff --git a/tests/ui/consts/recursive-zst-static.unleash.stderr b/tests/ui/consts/recursive-zst-static.unleash.stderr
index 5b4a0418b1e..7679c50c74b 100644
--- a/tests/ui/consts/recursive-zst-static.unleash.stderr
+++ b/tests/ui/consts/recursive-zst-static.unleash.stderr
@@ -1,21 +1,35 @@
-error[E0391]: cycle detected when const-evaluating + checking `FOO`
+error[E0080]: could not evaluate static initializer
   --> $DIR/recursive-zst-static.rs:10:18
    |
 LL | static FOO: () = FOO;
-   |                  ^^^
+   |                  ^^^ encountered static that tried to initialize itself with itself
+
+error[E0391]: cycle detected when evaluating initializer of static `A`
+  --> $DIR/recursive-zst-static.rs:13:16
+   |
+LL | static A: () = B;
+   |                ^
    |
-   = note: ...which immediately requires const-evaluating + checking `FOO` again
+note: ...which requires evaluating initializer of static `B`...
+  --> $DIR/recursive-zst-static.rs:14:16
+   |
+LL | static B: () = A;
+   |                ^
+   = note: ...which again requires evaluating initializer of static `A`, completing the cycle
 note: cycle used when linting top-level module
   --> $DIR/recursive-zst-static.rs:10:1
    |
 LL | / static FOO: () = FOO;
 LL | |
-LL | | fn main() {
+LL | |
+LL | | static A: () = B;
+...  |
 LL | |     FOO
 LL | | }
    | |_^
    = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0391`.
+Some errors have detailed explanations: E0080, E0391.
+For more information about an error, try `rustc --explain E0080`.
diff --git a/tests/ui/consts/write-to-static-mut-in-static.rs b/tests/ui/consts/write-to-static-mut-in-static.rs
index 43c63fed8ce..a2985d05a79 100644
--- a/tests/ui/consts/write-to-static-mut-in-static.rs
+++ b/tests/ui/consts/write-to-static-mut-in-static.rs
@@ -3,8 +3,8 @@ pub static mut B: () = unsafe { A = 1; };
 //~^ ERROR could not evaluate static initializer
 
 pub static mut C: u32 = unsafe { C = 1; 0 };
-//~^ ERROR cycle detected
 
 pub static D: u32 = D;
+//~^ ERROR could not evaluate static initializer
 
 fn main() {}
diff --git a/tests/ui/consts/write-to-static-mut-in-static.stderr b/tests/ui/consts/write-to-static-mut-in-static.stderr
index caee433a681..9616f8eeeb7 100644
--- a/tests/ui/consts/write-to-static-mut-in-static.stderr
+++ b/tests/ui/consts/write-to-static-mut-in-static.stderr
@@ -4,27 +4,12 @@ error[E0080]: could not evaluate static initializer
 LL | pub static mut B: () = unsafe { A = 1; };
    |                                 ^^^^^ modifying a static's initial value from another static's initializer
 
-error[E0391]: cycle detected when const-evaluating + checking `C`
-  --> $DIR/write-to-static-mut-in-static.rs:5:34
-   |
-LL | pub static mut C: u32 = unsafe { C = 1; 0 };
-   |                                  ^^^^^
-   |
-   = note: ...which immediately requires const-evaluating + checking `C` again
-note: cycle used when linting top-level module
-  --> $DIR/write-to-static-mut-in-static.rs:1:1
+error[E0080]: could not evaluate static initializer
+  --> $DIR/write-to-static-mut-in-static.rs:7:21
    |
-LL | / pub static mut A: u32 = 0;
-LL | | pub static mut B: () = unsafe { A = 1; };
-LL | |
-LL | |
-...  |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+LL | pub static D: u32 = D;
+   |                     ^ encountered static that tried to initialize itself with itself
 
 error: aborting due to 2 previous errors
 
-Some errors have detailed explanations: E0080, E0391.
-For more information about an error, try `rustc --explain E0080`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/error-codes/E0423.stderr b/tests/ui/error-codes/E0423.stderr
index ac70d905d35..dd7a5b034c5 100644
--- a/tests/ui/error-codes/E0423.stderr
+++ b/tests/ui/error-codes/E0423.stderr
@@ -53,7 +53,7 @@ help: use struct literal syntax instead
    |
 LL |     let f = Foo { a: val };
    |             ~~~~~~~~~~~~~~
-help: a function with a similar name exists
+help: a function with a similar name exists (notice the capitalization difference)
    |
 LL |     let f = foo();
    |             ~~~
diff --git a/tests/ui/impl-trait/where-allowed.rs b/tests/ui/impl-trait/where-allowed.rs
index 5ce63db684f..505e2d6c171 100644
--- a/tests/ui/impl-trait/where-allowed.rs
+++ b/tests/ui/impl-trait/where-allowed.rs
@@ -44,6 +44,7 @@ fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!() }
 
 // Allowed
 fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
+//~^ ERROR: type annotations needed
 
 // Disallowed
 fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
@@ -58,9 +59,11 @@ fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
 fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
 //~^ ERROR `impl Trait` is not allowed in the parameters of `Fn` trait bounds
 //~| ERROR nested `impl Trait` is not allowed
+//~| ERROR: type annotations needed
 
 // Allowed
 fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
+//~^ ERROR: type annotations needed
 
 // Disallowed
 fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
@@ -77,6 +80,7 @@ fn in_impl_Trait_in_parameters(_: impl Iterator<Item = impl Iterator>) { panic!(
 // Allowed
 fn in_impl_Trait_in_return() -> impl IntoIterator<Item = impl IntoIterator> {
     vec![vec![0; 10], vec![12; 7], vec![8; 3]]
+    //~^ ERROR: no function or associated item named `into_vec` found for slice `[_]`
 }
 
 // Disallowed
@@ -118,11 +122,13 @@ trait DummyTrait {
 impl DummyTrait for () {
     type Out = impl Debug;
     //~^ ERROR `impl Trait` in associated types is unstable
+    //~| ERROR unconstrained opaque type
 
     fn in_trait_impl_parameter(_: impl Debug) { }
     // Allowed
 
     fn in_trait_impl_return() -> impl Debug { () }
+    //~^ ERROR `in_trait_impl_return` has an incompatible type for trait
     // Allowed
 }
 
diff --git a/tests/ui/impl-trait/where-allowed.stderr b/tests/ui/impl-trait/where-allowed.stderr
index 3e1d4e22272..c22312cce19 100644
--- a/tests/ui/impl-trait/where-allowed.stderr
+++ b/tests/ui/impl-trait/where-allowed.stderr
@@ -1,5 +1,5 @@
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:49:51
+  --> $DIR/where-allowed.rs:50:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           --------^^^^^^^^^^-
@@ -8,7 +8,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                           outer `impl Trait`
 
 error[E0666]: nested `impl Trait` is not allowed
-  --> $DIR/where-allowed.rs:58:57
+  --> $DIR/where-allowed.rs:59:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                 --------^^^^^^^^^^-
@@ -17,7 +17,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    |                                                 outer `impl Trait`
 
 error[E0658]: `impl Trait` in associated types is unstable
-  --> $DIR/where-allowed.rs:119:16
+  --> $DIR/where-allowed.rs:123:16
    |
 LL |     type Out = impl Debug;
    |                ^^^^^^^^^^
@@ -27,7 +27,7 @@ LL |     type Out = impl Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:154:23
+  --> $DIR/where-allowed.rs:160:23
    |
 LL | type InTypeAlias<R> = impl Debug;
    |                       ^^^^^^^^^^
@@ -37,7 +37,7 @@ LL | type InTypeAlias<R> = impl Debug;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: `impl Trait` in type aliases is unstable
-  --> $DIR/where-allowed.rs:157:39
+  --> $DIR/where-allowed.rs:163:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -103,7 +103,7 @@ LL | fn in_dyn_Fn_parameter_in_return() -> &'static dyn Fn(impl Debug) { panic!(
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:49:51
+  --> $DIR/where-allowed.rs:50:51
    |
 LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    |                                                   ^^^^^^^^^^
@@ -111,7 +111,7 @@ LL | fn in_impl_Fn_parameter_in_parameters(_: &impl Fn(impl Debug)) { panic!() }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:54:53
+  --> $DIR/where-allowed.rs:55:53
    |
 LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!() }
    |                                                     ^^^^^^^^^^
@@ -119,7 +119,7 @@ LL | fn in_impl_Fn_return_in_parameters(_: &impl Fn() -> impl Debug) { panic!()
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:58:57
+  --> $DIR/where-allowed.rs:59:57
    |
 LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
    |                                                         ^^^^^^^^^^
@@ -127,7 +127,7 @@ LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:66:38
+  --> $DIR/where-allowed.rs:69:38
    |
 LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    |                                      ^^^^^^^^^^
@@ -135,7 +135,7 @@ LL | fn in_Fn_parameter_in_generics<F: Fn(impl Debug)> (_: F) { panic!() }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:70:40
+  --> $DIR/where-allowed.rs:73:40
    |
 LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    |                                        ^^^^^^^^^^
@@ -143,7 +143,7 @@ LL | fn in_Fn_return_in_generics<F: Fn() -> impl Debug> (_: F) { panic!() }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:83:32
+  --> $DIR/where-allowed.rs:87:32
    |
 LL | struct InBraceStructField { x: impl Debug }
    |                                ^^^^^^^^^^
@@ -151,7 +151,7 @@ LL | struct InBraceStructField { x: impl Debug }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:87:41
+  --> $DIR/where-allowed.rs:91:41
    |
 LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    |                                         ^^^^^^^^^^
@@ -159,7 +159,7 @@ LL | struct InAdtInBraceStructField { x: Vec<impl Debug> }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:91:27
+  --> $DIR/where-allowed.rs:95:27
    |
 LL | struct InTupleStructField(impl Debug);
    |                           ^^^^^^^^^^
@@ -167,7 +167,7 @@ LL | struct InTupleStructField(impl Debug);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:96:25
+  --> $DIR/where-allowed.rs:100:25
    |
 LL |     InBraceVariant { x: impl Debug },
    |                         ^^^^^^^^^^
@@ -175,7 +175,7 @@ LL |     InBraceVariant { x: impl Debug },
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in field types
-  --> $DIR/where-allowed.rs:98:20
+  --> $DIR/where-allowed.rs:102:20
    |
 LL |     InTupleVariant(impl Debug),
    |                    ^^^^^^^^^^
@@ -183,7 +183,7 @@ LL |     InTupleVariant(impl Debug),
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `extern fn` parameters
-  --> $DIR/where-allowed.rs:138:33
+  --> $DIR/where-allowed.rs:144:33
    |
 LL |     fn in_foreign_parameters(_: impl Debug);
    |                                 ^^^^^^^^^^
@@ -191,7 +191,7 @@ LL |     fn in_foreign_parameters(_: impl Debug);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `extern fn` return types
-  --> $DIR/where-allowed.rs:141:31
+  --> $DIR/where-allowed.rs:147:31
    |
 LL |     fn in_foreign_return() -> impl Debug;
    |                               ^^^^^^^^^^
@@ -199,7 +199,7 @@ LL |     fn in_foreign_return() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in `fn` pointer return types
-  --> $DIR/where-allowed.rs:157:39
+  --> $DIR/where-allowed.rs:163:39
    |
 LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    |                                       ^^^^^^^^^^
@@ -207,7 +207,7 @@ LL | type InReturnInTypeAlias<R> = fn() -> impl Debug;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in traits
-  --> $DIR/where-allowed.rs:162:16
+  --> $DIR/where-allowed.rs:168:16
    |
 LL | impl PartialEq<impl Debug> for () {
    |                ^^^^^^^^^^
@@ -215,7 +215,7 @@ LL | impl PartialEq<impl Debug> for () {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:167:24
+  --> $DIR/where-allowed.rs:173:24
    |
 LL | impl PartialEq<()> for impl Debug {
    |                        ^^^^^^^^^^
@@ -223,7 +223,7 @@ LL | impl PartialEq<()> for impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:172:6
+  --> $DIR/where-allowed.rs:178:6
    |
 LL | impl impl Debug {
    |      ^^^^^^^^^^
@@ -231,7 +231,7 @@ LL | impl impl Debug {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in impl headers
-  --> $DIR/where-allowed.rs:178:24
+  --> $DIR/where-allowed.rs:184:24
    |
 LL | impl InInherentImplAdt<impl Debug> {
    |                        ^^^^^^^^^^
@@ -239,7 +239,7 @@ LL | impl InInherentImplAdt<impl Debug> {
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:184:11
+  --> $DIR/where-allowed.rs:190:11
    |
 LL |     where impl Debug: Debug
    |           ^^^^^^^^^^
@@ -247,7 +247,7 @@ LL |     where impl Debug: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:191:15
+  --> $DIR/where-allowed.rs:197:15
    |
 LL |     where Vec<impl Debug>: Debug
    |               ^^^^^^^^^^
@@ -255,7 +255,7 @@ LL |     where Vec<impl Debug>: Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in bounds
-  --> $DIR/where-allowed.rs:198:24
+  --> $DIR/where-allowed.rs:204:24
    |
 LL |     where T: PartialEq<impl Debug>
    |                        ^^^^^^^^^^
@@ -263,7 +263,7 @@ LL |     where T: PartialEq<impl Debug>
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the parameters of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:205:17
+  --> $DIR/where-allowed.rs:211:17
    |
 LL |     where T: Fn(impl Debug)
    |                 ^^^^^^^^^^
@@ -271,7 +271,7 @@ LL |     where T: Fn(impl Debug)
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the return type of `Fn` trait bounds
-  --> $DIR/where-allowed.rs:212:22
+  --> $DIR/where-allowed.rs:218:22
    |
 LL |     where T: Fn() -> impl Debug
    |                      ^^^^^^^^^^
@@ -279,7 +279,7 @@ LL |     where T: Fn() -> impl Debug
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:218:40
+  --> $DIR/where-allowed.rs:224:40
    |
 LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    |                                        ^^^^^^^^^^
@@ -287,7 +287,7 @@ LL | struct InStructGenericParamDefault<T = impl Debug>(T);
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:222:36
+  --> $DIR/where-allowed.rs:228:36
    |
 LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    |                                    ^^^^^^^^^^
@@ -295,7 +295,7 @@ LL | enum InEnumGenericParamDefault<T = impl Debug> { Variant(T) }
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:226:38
+  --> $DIR/where-allowed.rs:232:38
    |
 LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    |                                      ^^^^^^^^^^
@@ -303,7 +303,7 @@ LL | trait InTraitGenericParamDefault<T = impl Debug> {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:230:41
+  --> $DIR/where-allowed.rs:236:41
    |
 LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    |                                         ^^^^^^^^^^
@@ -311,7 +311,7 @@ LL | type InTypeAliasGenericParamDefault<T = impl Debug> = T;
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:234:11
+  --> $DIR/where-allowed.rs:240:11
    |
 LL | impl <T = impl Debug> T {}
    |           ^^^^^^^^^^
@@ -319,7 +319,7 @@ LL | impl <T = impl Debug> T {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in generic parameter defaults
-  --> $DIR/where-allowed.rs:241:40
+  --> $DIR/where-allowed.rs:247:40
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                        ^^^^^^^^^^
@@ -327,7 +327,7 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in the type of variable bindings
-  --> $DIR/where-allowed.rs:247:29
+  --> $DIR/where-allowed.rs:253:29
    |
 LL |     let _in_local_variable: impl Fn() = || {};
    |                             ^^^^^^^^^
@@ -335,7 +335,7 @@ LL |     let _in_local_variable: impl Fn() = || {};
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error[E0562]: `impl Trait` is not allowed in closure return types
-  --> $DIR/where-allowed.rs:249:46
+  --> $DIR/where-allowed.rs:255:46
    |
 LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    |                                              ^^^^^^^^^
@@ -343,7 +343,7 @@ LL |     let _in_return_in_local_variable = || -> impl Fn() { || {} };
    = note: `impl Trait` is only allowed in arguments and return types of functions and methods
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:234:7
+  --> $DIR/where-allowed.rs:240:7
    |
 LL | impl <T = impl Debug> T {}
    |       ^^^^^^^^^^^^^^
@@ -353,7 +353,7 @@ LL | impl <T = impl Debug> T {}
    = note: `#[deny(invalid_type_param_default)]` on by default
 
 error: defaults for type parameters are only allowed in `struct`, `enum`, `type`, or `trait` definitions
-  --> $DIR/where-allowed.rs:241:36
+  --> $DIR/where-allowed.rs:247:36
    |
 LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    |                                    ^^^^^^^^^^^^^^
@@ -362,14 +362,77 @@ LL | fn in_method_generic_param_default<T = impl Debug>(_: T) {}
    = note: for more information, see issue #36887 <https://github.com/rust-lang/rust/issues/36887>
 
 error[E0118]: no nominal type found for inherent implementation
-  --> $DIR/where-allowed.rs:234:1
+  --> $DIR/where-allowed.rs:240:1
    |
 LL | impl <T = impl Debug> T {}
    | ^^^^^^^^^^^^^^^^^^^^^^^ impl requires a nominal type
    |
    = note: either implement a trait on it or create a newtype to wrap it instead
 
-error: aborting due to 45 previous errors
+error[E0283]: type annotations needed
+  --> $DIR/where-allowed.rs:46:57
+   |
+LL | fn in_dyn_Fn_return_in_return() -> &'static dyn Fn() -> impl Debug { panic!() }
+   |                                                         ^^^^^^^^^^ cannot infer type
+   |
+   = note: cannot satisfy `_: Debug`
+
+error[E0282]: type annotations needed
+  --> $DIR/where-allowed.rs:59:49
+   |
+LL | fn in_impl_Fn_parameter_in_return() -> &'static impl Fn(impl Debug) { panic!() }
+   |                                                 ^^^^^^^^^^^^^^^^^^^ cannot infer type
+
+error[E0283]: type annotations needed
+  --> $DIR/where-allowed.rs:65:46
+   |
+LL | fn in_impl_Fn_return_in_return() -> &'static impl Fn() -> impl Debug { panic!() }
+   |                                              ^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type
+   |
+   = note: multiple `impl`s satisfying `_: Fn()` found in the following crates: `alloc`, `core`:
+           - impl<A, F> Fn<A> for &F
+             where A: Tuple, F: Fn<A>, F: ?Sized;
+           - impl<Args, F, A> Fn<Args> for Box<F, A>
+             where Args: Tuple, F: Fn<Args>, A: Allocator, F: ?Sized;
+
+error[E0599]: no function or associated item named `into_vec` found for slice `[_]` in the current scope
+  --> $DIR/where-allowed.rs:82:5
+   |
+LL |     vec![vec![0; 10], vec![12; 7], vec![8; 3]]
+   |     ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ function or associated item not found in `[_]`
+   |
+   = note: this error originates in the macro `vec` (in Nightly builds, run with -Z macro-backtrace for more info)
+
+error[E0053]: method `in_trait_impl_return` has an incompatible type for trait
+  --> $DIR/where-allowed.rs:130:34
+   |
+LL |     type Out = impl Debug;
+   |                ---------- the expected opaque type
+...
+LL |     fn in_trait_impl_return() -> impl Debug { () }
+   |                                  ^^^^^^^^^^
+   |                                  |
+   |                                  expected opaque type, found a different opaque type
+   |                                  help: change the output type to match the trait: `<() as DummyTrait>::Out`
+   |
+note: type in trait
+  --> $DIR/where-allowed.rs:120:34
+   |
+LL |     fn in_trait_impl_return() -> Self::Out;
+   |                                  ^^^^^^^^^
+   = note: expected signature `fn() -> <() as DummyTrait>::Out`
+              found signature `fn() -> impl Debug`
+   = note: distinct uses of `impl Trait` result in different opaque types
+
+error: unconstrained opaque type
+  --> $DIR/where-allowed.rs:123:16
+   |
+LL |     type Out = impl Debug;
+   |                ^^^^^^^^^^
+   |
+   = note: `Out` must be used in combination with a concrete type within the same impl
+
+error: aborting due to 51 previous errors
 
-Some errors have detailed explanations: E0118, E0562, E0658, E0666.
-For more information about an error, try `rustc --explain E0118`.
+Some errors have detailed explanations: E0053, E0118, E0282, E0283, E0562, E0599, E0658, E0666.
+For more information about an error, try `rustc --explain E0053`.
diff --git a/tests/ui/issues/issue-4265.rs b/tests/ui/issues/issue-4265.rs
index 2596079d379..99b13283bc9 100644
--- a/tests/ui/issues/issue-4265.rs
+++ b/tests/ui/issues/issue-4265.rs
@@ -5,6 +5,7 @@ struct Foo {
 impl Foo {
     fn bar() {
         Foo { baz: 0 }.bar();
+        //~^ ERROR: no method named `bar` found
     }
 
     fn bar() { //~ ERROR duplicate definitions
diff --git a/tests/ui/issues/issue-4265.stderr b/tests/ui/issues/issue-4265.stderr
index 48b1c762e19..23d00aaa44b 100644
--- a/tests/ui/issues/issue-4265.stderr
+++ b/tests/ui/issues/issue-4265.stderr
@@ -1,5 +1,5 @@
 error[E0592]: duplicate definitions with name `bar`
-  --> $DIR/issue-4265.rs:10:5
+  --> $DIR/issue-4265.rs:11:5
    |
 LL |     fn bar() {
    |     -------- other definition for `bar`
@@ -7,6 +7,26 @@ LL |     fn bar() {
 LL |     fn bar() {
    |     ^^^^^^^^ duplicate definitions for `bar`
 
-error: aborting due to 1 previous error
+error[E0599]: no method named `bar` found for struct `Foo` in the current scope
+  --> $DIR/issue-4265.rs:7:24
+   |
+LL | struct Foo {
+   | ---------- method `bar` not found for this struct
+...
+LL |         Foo { baz: 0 }.bar();
+   |         ---------------^^^--
+   |         |              |
+   |         |              this is an associated function, not a method
+   |         help: use associated function syntax instead: `Foo::bar()`
+   |
+   = note: found the following associated functions; to be used as methods, functions must have a `self` parameter
+note: the candidate is defined in an impl for the type `Foo`
+  --> $DIR/issue-4265.rs:6:5
+   |
+LL |     fn bar() {
+   |     ^^^^^^^^
+
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0592`.
+Some errors have detailed explanations: E0592, E0599.
+For more information about an error, try `rustc --explain E0592`.
diff --git a/tests/ui/kinds-of-primitive-impl.rs b/tests/ui/kinds-of-primitive-impl.rs
index 6a067a9a360..f1c2ee8e550 100644
--- a/tests/ui/kinds-of-primitive-impl.rs
+++ b/tests/ui/kinds-of-primitive-impl.rs
@@ -6,7 +6,7 @@ impl u8 {
 impl str {
 //~^ error: cannot define inherent `impl` for primitive types
     fn foo() {}
-    fn bar(self) {}
+    fn bar(self) {} //~ ERROR: size for values of type `str` cannot be known
 }
 
 impl char {
diff --git a/tests/ui/kinds-of-primitive-impl.stderr b/tests/ui/kinds-of-primitive-impl.stderr
index 21aac58f1f2..1c8c417e88c 100644
--- a/tests/ui/kinds-of-primitive-impl.stderr
+++ b/tests/ui/kinds-of-primitive-impl.stderr
@@ -31,6 +31,20 @@ LL | impl &MyType {
    = help: consider using an extension trait instead
    = note: you could also try moving the reference to uses of `MyType` (such as `self`) within the implementation
 
-error: aborting due to 4 previous errors
+error[E0277]: the size for values of type `str` cannot be known at compilation time
+  --> $DIR/kinds-of-primitive-impl.rs:9:12
+   |
+LL |     fn bar(self) {}
+   |            ^^^^ doesn't have a size known at compile-time
+   |
+   = help: the trait `Sized` is not implemented for `str`
+   = help: unsized fn params are gated as an unstable feature
+help: function arguments must have a statically known size, borrowed types always have a known size
+   |
+LL |     fn bar(&self) {}
+   |            +
+
+error: aborting due to 5 previous errors
 
-For more information about this error, try `rustc --explain E0390`.
+Some errors have detailed explanations: E0277, E0390.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/lint/reference_casting.rs b/tests/ui/lint/reference_casting.rs
index 63541943d65..e5d84e464fd 100644
--- a/tests/ui/lint/reference_casting.rs
+++ b/tests/ui/lint/reference_casting.rs
@@ -239,6 +239,11 @@ unsafe fn bigger_layout() {
         //~^ ERROR casting references to a bigger memory layout
     }
 
+    {
+        let x: Box<dyn Send> = Box::new(0i32);
+        let _z = unsafe { &*(&*x as *const dyn Send as *const i32) };
+    }
+
     unsafe fn from_ref(this: &i32) -> &i64 {
         &*(this as *const i32 as *const i64)
     }
diff --git a/tests/ui/mir/mir_query_cycle.rs b/tests/ui/mir/mir_query_cycle.rs
new file mode 100644
index 00000000000..22d1ccb6c6e
--- /dev/null
+++ b/tests/ui/mir/mir_query_cycle.rs
@@ -0,0 +1,14 @@
+// Regression test for #121094.
+// build-pass
+// compile-flags: -O --crate-type=lib
+// edition: 2021
+use std::{future::Future, pin::Pin};
+
+pub async fn foo(count: u32) {
+    if count == 0 {
+        return
+    } else {
+        let fut: Pin<Box<dyn Future<Output = ()>>> = Box::pin(foo(count - 1));
+        fut.await;
+    }
+}
diff --git a/tests/ui/parser/emoji-identifiers.stderr b/tests/ui/parser/emoji-identifiers.stderr
index 8250dd1ea2e..1fc561d32c6 100644
--- a/tests/ui/parser/emoji-identifiers.stderr
+++ b/tests/ui/parser/emoji-identifiers.stderr
@@ -9,14 +9,6 @@ help: Unicode character 'โž–' (Heavy Minus Sign) looks like '-' (Minus/Hyphen),
 LL |     let _ = i_like_to_๐Ÿ˜„_a_lot() - 4;
    |                                  ~
 
-error: Ferris cannot be used as an identifier
-  --> $DIR/emoji-identifiers.rs:17:9
-   |
-LL |     let ๐Ÿฆ€ = 1;
-   |         ^^ help: try using their name instead: `ferris`
-LL |     dbg!(๐Ÿฆ€);
-   |          ^^
-
 error: identifiers cannot contain emoji: `ABig๐Ÿ‘ฉ๐Ÿ‘ฉ๐Ÿ‘ง๐Ÿ‘งFamily`
   --> $DIR/emoji-identifiers.rs:1:8
    |
@@ -64,6 +56,14 @@ error: identifiers cannot contain emoji: `i_like_to_๐Ÿ˜„_a_lot`
 LL |     let _ = i_like_to_๐Ÿ˜„_a_lot() โž– 4;
    |             ^^^^^^^^^^^^^^^^^^
 
+error: Ferris cannot be used as an identifier
+  --> $DIR/emoji-identifiers.rs:17:9
+   |
+LL |     let ๐Ÿฆ€ = 1;
+   |         ^^ help: try using their name instead: `ferris`
+LL |     dbg!(๐Ÿฆ€);
+   |          ^^
+
 error[E0599]: no function or associated item named `full_ofโœจ` found for struct `๐Ÿ‘€` in the current scope
   --> $DIR/emoji-identifiers.rs:9:8
    |
diff --git a/tests/ui/parser/impl-item-type-no-body-semantic-fail.rs b/tests/ui/parser/impl-item-type-no-body-semantic-fail.rs
index 5582e82d11d..bbd207be06d 100644
--- a/tests/ui/parser/impl-item-type-no-body-semantic-fail.rs
+++ b/tests/ui/parser/impl-item-type-no-body-semantic-fail.rs
@@ -14,8 +14,10 @@ impl X {
     //~^ ERROR associated type in `impl` without body
     //~| ERROR bounds on `type`s in `impl`s have no effect
     //~| ERROR inherent associated types are unstable
+    //~| ERROR `X: Eq` is not satisfied
     type W where Self: Eq;
     //~^ ERROR associated type in `impl` without body
     //~| ERROR inherent associated types are unstable
     //~| ERROR duplicate definitions
+    //~| ERROR `X: Eq` is not satisfied
 }
diff --git a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
index d23e6027473..1c71cdacd89 100644
--- a/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
+++ b/tests/ui/parser/impl-item-type-no-body-semantic-fail.stderr
@@ -35,7 +35,7 @@ LL |     type W: Ord where Self: Eq;
    |             ^^^
 
 error: associated type in `impl` without body
-  --> $DIR/impl-item-type-no-body-semantic-fail.rs:17:5
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5
    |
 LL |     type W where Self: Eq;
    |     ^^^^^^^^^^^^^^^^^^^^^-
@@ -73,7 +73,7 @@ LL |     type W: Ord where Self: Eq;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0658]: inherent associated types are unstable
-  --> $DIR/impl-item-type-no-body-semantic-fail.rs:17:5
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5
    |
 LL |     type W where Self: Eq;
    |     ^^^^^^^^^^^^^^^^^^^^^^
@@ -83,7 +83,7 @@ LL |     type W where Self: Eq;
    = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
 
 error[E0592]: duplicate definitions with name `W`
-  --> $DIR/impl-item-type-no-body-semantic-fail.rs:17:5
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:5
    |
 LL |     type W: Ord where Self: Eq;
    |     ------ other definition for `W`
@@ -91,7 +91,35 @@ LL |     type W: Ord where Self: Eq;
 LL |     type W where Self: Eq;
    |     ^^^^^^ duplicate definitions for `W`
 
-error: aborting due to 11 previous errors
+error[E0277]: the trait bound `X: Eq` is not satisfied
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:13:23
+   |
+LL |     type W: Ord where Self: Eq;
+   |                       ^^^^^^^^ the trait `Eq` is not implemented for `X`
+   |
+   = help: see issue #48214
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+help: consider annotating `X` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct X;
+   |
+
+error[E0277]: the trait bound `X: Eq` is not satisfied
+  --> $DIR/impl-item-type-no-body-semantic-fail.rs:18:18
+   |
+LL |     type W where Self: Eq;
+   |                  ^^^^^^^^ the trait `Eq` is not implemented for `X`
+   |
+   = help: see issue #48214
+   = help: add `#![feature(trivial_bounds)]` to the crate attributes to enable
+help: consider annotating `X` with `#[derive(Eq)]`
+   |
+LL + #[derive(Eq)]
+LL | struct X;
+   |
+
+error: aborting due to 13 previous errors
 
-Some errors have detailed explanations: E0592, E0658.
-For more information about an error, try `rustc --explain E0592`.
+Some errors have detailed explanations: E0277, E0592, E0658.
+For more information about an error, try `rustc --explain E0277`.
diff --git a/tests/ui/parser/kw-in-trait-bounds.stderr b/tests/ui/parser/kw-in-trait-bounds.stderr
index 2d3aad4d6ba..3c54e031950 100644
--- a/tests/ui/parser/kw-in-trait-bounds.stderr
+++ b/tests/ui/parser/kw-in-trait-bounds.stderr
@@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |          ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | fn _f<F: Fn(), G>(_: impl fn(), _: &dyn fn())
    |          ~~
@@ -15,7 +15,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |                           ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | fn _f<F: fn(), G>(_: impl Fn(), _: &dyn fn())
    |                           ~~
@@ -26,7 +26,7 @@ error: expected identifier, found keyword `fn`
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn fn())
    |                                         ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | fn _f<F: fn(), G>(_: impl fn(), _: &dyn Fn())
    |                                         ~~
@@ -37,7 +37,7 @@ error: expected identifier, found keyword `fn`
 LL | G: fn(),
    |    ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | G: Fn(),
    |    ~~
diff --git a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
index 17138a6f079..aee31d08fe0 100644
--- a/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
+++ b/tests/ui/parser/recover/recover-fn-trait-from-fn-kw.stderr
@@ -4,7 +4,7 @@ error: expected identifier, found keyword `fn`
 LL | fn foo(_: impl fn() -> i32) {}
    |                ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | fn foo(_: impl Fn() -> i32) {}
    |                ~~
@@ -15,7 +15,7 @@ error: expected identifier, found keyword `fn`
 LL | fn foo2<T: fn(i32)>(_: T) {}
    |            ^^
    |
-help: use `Fn` to refer to the trait
+help: use `Fn` to refer to the trait (notice the capitalization difference)
    |
 LL | fn foo2<T: Fn(i32)>(_: T) {}
    |            ~~
diff --git a/tests/ui/parser/typod-const-in-const-param-def.stderr b/tests/ui/parser/typod-const-in-const-param-def.stderr
index 75d73c6ea87..80c0f1deae6 100644
--- a/tests/ui/parser/typod-const-in-const-param-def.stderr
+++ b/tests/ui/parser/typod-const-in-const-param-def.stderr
@@ -4,7 +4,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn foo<Const N: u8>() {}
    |            ^^^^^
    |
-help: use the `const` keyword
+help: use the `const` keyword (notice the capitalization difference)
    |
 LL | pub fn foo<const N: u8>() {}
    |            ~~~~~
@@ -15,7 +15,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn baz<Const N: u8, T>() {}
    |            ^^^^^
    |
-help: use the `const` keyword
+help: use the `const` keyword (notice the capitalization difference)
    |
 LL | pub fn baz<const N: u8, T>() {}
    |            ~~~~~
@@ -26,7 +26,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn qux<T, Const N: u8>() {}
    |               ^^^^^
    |
-help: use the `const` keyword
+help: use the `const` keyword (notice the capitalization difference)
    |
 LL | pub fn qux<T, const N: u8>() {}
    |               ~~~~~
@@ -37,7 +37,7 @@ error: `const` keyword was mistyped as `Const`
 LL | pub fn quux<T, Const N: u8, U>() {}
    |                ^^^^^
    |
-help: use the `const` keyword
+help: use the `const` keyword (notice the capitalization difference)
    |
 LL | pub fn quux<T, const N: u8, U>() {}
    |                ~~~~~
diff --git a/tests/ui/recursion/recursive-static-definition.rs b/tests/ui/recursion/recursive-static-definition.rs
index f59ef7316d8..5317c47076e 100644
--- a/tests/ui/recursion/recursive-static-definition.rs
+++ b/tests/ui/recursion/recursive-static-definition.rs
@@ -1,4 +1,12 @@
 pub static FOO: u32 = FOO;
-//~^ ERROR cycle detected when const-evaluating + checking `FOO`
+//~^ ERROR could not evaluate static initializer
+
+#[derive(Copy, Clone)]
+pub union Foo {
+    x: u32,
+}
+
+pub static BAR: Foo = BAR;
+//~^ ERROR could not evaluate static initializer
 
 fn main() {}
diff --git a/tests/ui/recursion/recursive-static-definition.stderr b/tests/ui/recursion/recursive-static-definition.stderr
index 4fc3ee68ebc..86a22c990e9 100644
--- a/tests/ui/recursion/recursive-static-definition.stderr
+++ b/tests/ui/recursion/recursive-static-definition.stderr
@@ -1,20 +1,15 @@
-error[E0391]: cycle detected when const-evaluating + checking `FOO`
+error[E0080]: could not evaluate static initializer
   --> $DIR/recursive-static-definition.rs:1:23
    |
 LL | pub static FOO: u32 = FOO;
-   |                       ^^^
-   |
-   = note: ...which immediately requires const-evaluating + checking `FOO` again
-note: cycle used when linting top-level module
-  --> $DIR/recursive-static-definition.rs:1:1
+   |                       ^^^ encountered static that tried to initialize itself with itself
+
+error[E0080]: could not evaluate static initializer
+  --> $DIR/recursive-static-definition.rs:9:23
    |
-LL | / pub static FOO: u32 = FOO;
-LL | |
-LL | |
-LL | | fn main() {}
-   | |____________^
-   = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information
+LL | pub static BAR: Foo = BAR;
+   |                       ^^^ encountered static that tried to initialize itself with itself
 
-error: aborting due to 1 previous error
+error: aborting due to 2 previous errors
 
-For more information about this error, try `rustc --explain E0391`.
+For more information about this error, try `rustc --explain E0080`.
diff --git a/tests/ui/statics/recursive_interior_mut.rs b/tests/ui/statics/recursive_interior_mut.rs
new file mode 100644
index 00000000000..7e3083909d5
--- /dev/null
+++ b/tests/ui/statics/recursive_interior_mut.rs
@@ -0,0 +1,20 @@
+// check-pass
+
+use std::cell::Cell;
+use std::ptr::NonNull;
+
+struct ChunkFooter {
+    prev: Cell<NonNull<ChunkFooter>>,
+}
+
+struct EmptyChunkFooter(ChunkFooter);
+
+unsafe impl Sync for EmptyChunkFooter {}
+
+static EMPTY_CHUNK: EmptyChunkFooter = EmptyChunkFooter(ChunkFooter {
+    prev: Cell::new(unsafe {
+        NonNull::new_unchecked(&EMPTY_CHUNK as *const EmptyChunkFooter as *mut ChunkFooter)
+    }),
+});
+
+fn main() {}
diff --git a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
index 211cb1584ad..8f00a72f1e8 100644
--- a/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
+++ b/tests/ui/suggestions/assoc-ct-for-assoc-method.stderr
@@ -8,7 +8,7 @@ LL |     let x: i32 = MyS::foo;
    |
    = note: expected type `i32`
            found fn item `fn() -> MyS {MyS::foo}`
-help: try referring to the associated const `FOO` instead
+help: try referring to the associated const `FOO` instead (notice the capitalization difference)
    |
 LL |     let x: i32 = MyS::FOO;
    |                       ~~~
diff --git a/tests/ui/suggestions/bool_typo_err_suggest.stderr b/tests/ui/suggestions/bool_typo_err_suggest.stderr
index 52bde07ca07..8d59ed63e54 100644
--- a/tests/ui/suggestions/bool_typo_err_suggest.stderr
+++ b/tests/ui/suggestions/bool_typo_err_suggest.stderr
@@ -15,7 +15,7 @@ error[E0425]: cannot find value `False` in this scope
 LL |     let y = False;
    |             ^^^^^ not found in this scope
    |
-help: you may want to use a bool value instead
+help: you may want to use a bool value instead (notice the capitalization difference)
    |
 LL |     let y = false;
    |             ~~~~~
diff --git a/tests/ui/traits/issue-33140.rs b/tests/ui/traits/issue-33140.rs
index 9bdac4b8375..01b16f76be5 100644
--- a/tests/ui/traits/issue-33140.rs
+++ b/tests/ui/traits/issue-33140.rs
@@ -43,5 +43,7 @@ fn main() {
     assert_eq!(<dyn Send + Sync>::uvw(), false);
     assert_eq!(<dyn Sync + Send+ Sync>::uvw(), true);
     assert_eq!(<Foo<dyn Send + Sync>>::abc(), false);
+    //~^ ERROR: multiple applicable items in scope
     assert_eq!(<Foo<dyn Sync + Send>>::abc(), true);
+    //~^ ERROR: multiple applicable items in scope
 }
diff --git a/tests/ui/traits/issue-33140.stderr b/tests/ui/traits/issue-33140.stderr
index d31281f7256..7d7ee96f209 100644
--- a/tests/ui/traits/issue-33140.stderr
+++ b/tests/ui/traits/issue-33140.stderr
@@ -25,7 +25,41 @@ LL |     fn abc() -> bool {
 LL |     fn abc() -> bool {
    |     ---------------- other definition for `abc`
 
-error: aborting due to 3 previous errors
+error[E0034]: multiple applicable items in scope
+  --> $DIR/issue-33140.rs:45:40
+   |
+LL |     assert_eq!(<Foo<dyn Send + Sync>>::abc(), false);
+   |                                        ^^^ multiple `abc` found
+   |
+note: candidate #1 is defined in an impl for the type `Foo<(dyn Send + Sync + 'static)>`
+  --> $DIR/issue-33140.rs:29:5
+   |
+LL |     fn abc() -> bool {
+   |     ^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Foo<(dyn Send + Sync + 'static)>`
+  --> $DIR/issue-33140.rs:35:5
+   |
+LL |     fn abc() -> bool {
+   |     ^^^^^^^^^^^^^^^^
+
+error[E0034]: multiple applicable items in scope
+  --> $DIR/issue-33140.rs:47:40
+   |
+LL |     assert_eq!(<Foo<dyn Sync + Send>>::abc(), true);
+   |                                        ^^^ multiple `abc` found
+   |
+note: candidate #1 is defined in an impl for the type `Foo<(dyn Send + Sync + 'static)>`
+  --> $DIR/issue-33140.rs:29:5
+   |
+LL |     fn abc() -> bool {
+   |     ^^^^^^^^^^^^^^^^
+note: candidate #2 is defined in an impl for the type `Foo<(dyn Send + Sync + 'static)>`
+  --> $DIR/issue-33140.rs:35:5
+   |
+LL |     fn abc() -> bool {
+   |     ^^^^^^^^^^^^^^^^
+
+error: aborting due to 5 previous errors
 
-Some errors have detailed explanations: E0119, E0592.
-For more information about an error, try `rustc --explain E0119`.
+Some errors have detailed explanations: E0034, E0119, E0592.
+For more information about an error, try `rustc --explain E0034`.
diff --git a/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs b/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs
new file mode 100644
index 00000000000..7e242ed9126
--- /dev/null
+++ b/tests/ui/traits/trait-upcasting/add-supertrait-auto-traits.rs
@@ -0,0 +1,14 @@
+// check-pass
+// revisions: current next
+//[next] compile-flags: -Znext-solver
+
+#![feature(trait_upcasting)]
+
+trait Target {}
+trait Source: Send + Target {}
+
+fn upcast(x: &dyn Source) -> &(dyn Target + Send) { x }
+
+fn same(x: &dyn Source) -> &(dyn Source + Send) { x }
+
+fn main() {}
diff --git a/tests/ui/treat-err-as-bug/err.rs b/tests/ui/treat-err-as-bug/err.rs
index 4090a706f99..74992497dab 100644
--- a/tests/ui/treat-err-as-bug/err.rs
+++ b/tests/ui/treat-err-as-bug/err.rs
@@ -1,7 +1,7 @@
 // compile-flags: -Ztreat-err-as-bug
 // failure-status: 101
 // error-pattern: aborting due to `-Z treat-err-as-bug=1`
-// error-pattern: [eval_to_allocation_raw] const-evaluating + checking `C`
+// error-pattern: [eval_static_initializer] evaluating initializer of static `C`
 // normalize-stderr-test "note: .*\n\n" -> ""
 // normalize-stderr-test "thread 'rustc' panicked.*:\n.*\n" -> ""
 // rustc-env:RUST_BACKTRACE=0
diff --git a/tests/ui/treat-err-as-bug/err.stderr b/tests/ui/treat-err-as-bug/err.stderr
index f1b61c3607b..ca04ee9e0cf 100644
--- a/tests/ui/treat-err-as-bug/err.stderr
+++ b/tests/ui/treat-err-as-bug/err.stderr
@@ -7,6 +7,6 @@ LL | pub static C: u32 = 0 - 1;
 error: the compiler unexpectedly panicked. this is a bug.
 
 query stack during panic:
-#0 [eval_to_allocation_raw] const-evaluating + checking `C`
+#0 [eval_static_initializer] evaluating initializer of static `C`
 #1 [lint_mod] linting top-level module
 end of query stack