about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_ast_lowering/src/item.rs50
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/demand.rs14
-rw-r--r--compiler/rustc_hir_typeck/src/gather_locals.rs7
-rw-r--r--compiler/rustc_hir_typeck/src/writeback.rs70
-rw-r--r--compiler/rustc_metadata/messages.ftl2
-rw-r--r--compiler/rustc_pattern_analysis/src/rustc.rs40
-rw-r--r--compiler/rustc_type_ir/src/region_kind.rs2
-rw-r--r--src/doc/rustc-dev-guide/rust-version2
-rw-r--r--src/doc/rustc-dev-guide/src/SUMMARY.md2
-rw-r--r--src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md27
-rw-r--r--src/doc/rustc-dev-guide/src/cli.md2
-rw-r--r--src/doc/rustc-dev-guide/src/getting-started.md2
-rw-r--r--src/doc/rustc-dev-guide/src/rustc-driver/intro.md12
-rw-r--r--tests/crashes/140823.rs9
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.rs2
-rw-r--r--tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr2
-rw-r--r--tests/ui/fn/coerce-suggestion-infer-region.rs26
-rw-r--r--tests/ui/fn/coerce-suggestion-infer-region.stderr12
-rw-r--r--tests/ui/impl-trait/issues/issue-100075-2.stderr15
-rw-r--r--tests/ui/impl-trait/issues/issue-100075.stderr5
-rw-r--r--tests/ui/impl-trait/issues/issue-103599.rs5
-rw-r--r--tests/ui/impl-trait/issues/issue-103599.stderr13
-rw-r--r--tests/ui/impl-trait/issues/issue-87450.rs4
-rw-r--r--tests/ui/impl-trait/issues/issue-87450.stderr18
-rw-r--r--tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr73
-rw-r--r--tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr53
-rw-r--r--tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr18
-rw-r--r--tests/ui/impl-trait/recursive-in-exhaustiveness.rs6
-rw-r--r--tests/ui/pattern/rfc-3637-guard-patterns/only-gather-locals-once.rs15
-rw-r--r--tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr6
-rw-r--r--tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.rs (renamed from tests/crashes/139817.rs)6
-rw-r--r--tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr11
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr9
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs2
-rw-r--r--tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr11
40 files changed, 279 insertions, 303 deletions
diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs
index f48a571b86a..e98d6c50ee7 100644
--- a/compiler/rustc_ast_lowering/src/item.rs
+++ b/compiler/rustc_ast_lowering/src/item.rs
@@ -70,44 +70,32 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
         }
     }
 
-    pub(super) fn lower_node(&mut self, def_id: LocalDefId) -> hir::MaybeOwner<'hir> {
+    pub(super) fn lower_node(&mut self, def_id: LocalDefId) {
         let owner = self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
         if let hir::MaybeOwner::Phantom = owner {
             let node = self.ast_index[def_id];
             match node {
                 AstOwner::NonOwner => {}
-                AstOwner::Crate(c) => self.lower_crate(c),
-                AstOwner::Item(item) => self.lower_item(item),
-                AstOwner::AssocItem(item, ctxt) => self.lower_assoc_item(item, ctxt),
-                AstOwner::ForeignItem(item) => self.lower_foreign_item(item),
+                AstOwner::Crate(c) => {
+                    debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
+                    self.with_lctx(CRATE_NODE_ID, |lctx| {
+                        let module = lctx.lower_mod(&c.items, &c.spans);
+                        // FIXME(jdonszelman): is dummy span ever a problem here?
+                        lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
+                        hir::OwnerNode::Crate(module)
+                    })
+                }
+                AstOwner::Item(item) => {
+                    self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
+                }
+                AstOwner::AssocItem(item, ctxt) => {
+                    self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
+                }
+                AstOwner::ForeignItem(item) => self.with_lctx(item.id, |lctx| {
+                    hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item))
+                }),
             }
         }
-
-        self.owners[def_id]
-    }
-
-    #[instrument(level = "debug", skip(self, c))]
-    fn lower_crate(&mut self, c: &Crate) {
-        debug_assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID);
-        self.with_lctx(CRATE_NODE_ID, |lctx| {
-            let module = lctx.lower_mod(&c.items, &c.spans);
-            // FIXME(jdonszelman): is dummy span ever a problem here?
-            lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, DUMMY_SP);
-            hir::OwnerNode::Crate(module)
-        })
-    }
-
-    #[instrument(level = "debug", skip(self))]
-    fn lower_item(&mut self, item: &Item) {
-        self.with_lctx(item.id, |lctx| hir::OwnerNode::Item(lctx.lower_item(item)))
-    }
-
-    fn lower_assoc_item(&mut self, item: &AssocItem, ctxt: AssocCtxt) {
-        self.with_lctx(item.id, |lctx| lctx.lower_assoc_item(item, ctxt))
-    }
-
-    fn lower_foreign_item(&mut self, item: &ForeignItem) {
-        self.with_lctx(item.id, |lctx| hir::OwnerNode::ForeignItem(lctx.lower_foreign_item(item)))
     }
 }
 
diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs
index 19095f2e01e..422e79ca82f 100644
--- a/compiler/rustc_ast_lowering/src/lib.rs
+++ b/compiler/rustc_ast_lowering/src/lib.rs
@@ -444,14 +444,14 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> {
         tcx.definitions_untracked().def_index_count(),
     );
 
+    let mut lowerer = item::ItemLowerer {
+        tcx,
+        resolver: &mut resolver,
+        ast_index: &ast_index,
+        owners: &mut owners,
+    };
     for def_id in ast_index.indices() {
-        item::ItemLowerer {
-            tcx,
-            resolver: &mut resolver,
-            ast_index: &ast_index,
-            owners: &mut owners,
-        }
-        .lower_node(def_id);
+        lowerer.lower_node(def_id);
     }
 
     drop(ast_index);
diff --git a/compiler/rustc_hir_typeck/src/demand.rs b/compiler/rustc_hir_typeck/src/demand.rs
index d1bc54ed73e..8182851a015 100644
--- a/compiler/rustc_hir_typeck/src/demand.rs
+++ b/compiler/rustc_hir_typeck/src/demand.rs
@@ -84,7 +84,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
 
         self.annotate_expected_due_to_let_ty(err, expr, error);
         self.annotate_loop_expected_due_to_inference(err, expr, error);
-        if self.annotate_mut_binding_to_immutable_binding(err, expr, error) {
+        if self.annotate_mut_binding_to_immutable_binding(err, expr, expr_ty, expected, error) {
             return;
         }
 
@@ -799,17 +799,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
     /// Detect the following case
     ///
     /// ```text
-    /// fn change_object(mut a: &Ty) {
+    /// fn change_object(mut b: &Ty) {
     ///     let a = Ty::new();
     ///     b = a;
     /// }
     /// ```
     ///
-    /// where the user likely meant to modify the value behind there reference, use `a` as an out
+    /// where the user likely meant to modify the value behind there reference, use `b` as an out
     /// parameter, instead of mutating the local binding. When encountering this we suggest:
     ///
     /// ```text
-    /// fn change_object(a: &'_ mut Ty) {
+    /// fn change_object(b: &'_ mut Ty) {
     ///     let a = Ty::new();
     ///     *b = a;
     /// }
@@ -818,13 +818,15 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
         &self,
         err: &mut Diag<'_>,
         expr: &hir::Expr<'_>,
+        expr_ty: Ty<'tcx>,
+        expected: Ty<'tcx>,
         error: Option<TypeError<'tcx>>,
     ) -> bool {
-        if let Some(TypeError::Sorts(ExpectedFound { expected, found })) = error
+        if let Some(TypeError::Sorts(ExpectedFound { .. })) = error
             && let ty::Ref(_, inner, hir::Mutability::Not) = expected.kind()
 
             // The difference between the expected and found values is one level of borrowing.
-            && self.can_eq(self.param_env, *inner, found)
+            && self.can_eq(self.param_env, *inner, expr_ty)
 
             // We have an `ident = expr;` assignment.
             && let hir::Node::Expr(hir::Expr { kind: hir::ExprKind::Assign(lhs, rhs, _), .. }) =
diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs
index 956671fc66e..7d99b0e7869 100644
--- a/compiler/rustc_hir_typeck/src/gather_locals.rs
+++ b/compiler/rustc_hir_typeck/src/gather_locals.rs
@@ -218,7 +218,12 @@ impl<'a, 'tcx> Visitor<'tcx> for GatherLocalsVisitor<'a, 'tcx> {
             );
         }
         let old_outermost_fn_param_pat = self.outermost_fn_param_pat.take();
-        intravisit::walk_pat(self, p);
+        if let PatKind::Guard(subpat, _) = p.kind {
+            // We'll visit the guard when checking it. Don't gather its locals twice.
+            self.visit_pat(subpat);
+        } else {
+            intravisit::walk_pat(self, p);
+        }
         self.outermost_fn_param_pat = old_outermost_fn_param_pat;
     }
 
diff --git a/compiler/rustc_hir_typeck/src/writeback.rs b/compiler/rustc_hir_typeck/src/writeback.rs
index 9be041f75d7..b2497cb0de1 100644
--- a/compiler/rustc_hir_typeck/src/writeback.rs
+++ b/compiler/rustc_hir_typeck/src/writeback.rs
@@ -9,17 +9,21 @@
 //! which creates a new `TypeckResults` which doesn't contain any inference variables.
 
 use std::mem;
+use std::ops::ControlFlow;
 
+use rustc_data_structures::fx::{FxHashSet, FxIndexMap};
 use rustc_data_structures::unord::ExtendUnord;
-use rustc_errors::ErrorGuaranteed;
+use rustc_errors::{E0720, ErrorGuaranteed};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit::{self, InferKind, Visitor};
 use rustc_hir::{self as hir, AmbigArg, HirId};
 use rustc_infer::traits::solve::Goal;
 use rustc_middle::traits::ObligationCause;
 use rustc_middle::ty::adjustment::{Adjust, Adjustment, PointerCoercion};
 use rustc_middle::ty::{
-    self, DefiningScopeKind, Ty, TyCtxt, TypeFoldable, TypeFolder, TypeSuperFoldable,
-    TypeVisitableExt, fold_regions,
+    self, DefiningScopeKind, OpaqueHiddenType, Ty, TyCtxt, TypeFoldable, TypeFolder,
+    TypeSuperFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt, TypeVisitor,
+    fold_regions,
 };
 use rustc_span::{Span, sym};
 use rustc_trait_selection::error_reporting::infer::need_type_info::TypeAnnotationNeeded;
@@ -595,6 +599,35 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
                 entry.span = prev.span.substitute_dummy(hidden_type.span);
             }
         }
+
+        let recursive_opaques: Vec<_> = self
+            .typeck_results
+            .concrete_opaque_types
+            .iter()
+            .filter(|&(&def_id, hidden_ty)| {
+                hidden_ty
+                    .ty
+                    .visit_with(&mut HasRecursiveOpaque {
+                        def_id,
+                        seen: Default::default(),
+                        opaques: &self.typeck_results.concrete_opaque_types,
+                        tcx,
+                    })
+                    .is_break()
+            })
+            .map(|(def_id, hidden_ty)| (*def_id, hidden_ty.span))
+            .collect();
+        for (def_id, span) in recursive_opaques {
+            let guar = self
+                .fcx
+                .dcx()
+                .struct_span_err(span, "cannot resolve opaque type")
+                .with_code(E0720)
+                .emit();
+            self.typeck_results
+                .concrete_opaque_types
+                .insert(def_id, OpaqueHiddenType { span, ty: Ty::new_error(tcx, guar) });
+        }
     }
 
     fn visit_field_id(&mut self, hir_id: HirId) {
@@ -959,3 +992,34 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for EagerlyNormalizeConsts<'tcx> {
         self.tcx.try_normalize_erasing_regions(self.typing_env, ct).unwrap_or(ct)
     }
 }
+
+struct HasRecursiveOpaque<'a, 'tcx> {
+    def_id: LocalDefId,
+    seen: FxHashSet<LocalDefId>,
+    opaques: &'a FxIndexMap<LocalDefId, ty::OpaqueHiddenType<'tcx>>,
+    tcx: TyCtxt<'tcx>,
+}
+
+impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for HasRecursiveOpaque<'_, 'tcx> {
+    type Result = ControlFlow<()>;
+
+    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
+        if let ty::Alias(ty::Opaque, alias_ty) = *t.kind()
+            && let Some(def_id) = alias_ty.def_id.as_local()
+        {
+            if self.def_id == def_id {
+                return ControlFlow::Break(());
+            }
+
+            if self.seen.insert(def_id)
+                && let Some(hidden_ty) = self.opaques.get(&def_id)
+            {
+                ty::EarlyBinder::bind(hidden_ty.ty)
+                    .instantiate(self.tcx, alias_ty.args)
+                    .visit_with(self)?;
+            }
+        }
+
+        t.super_visit_with(self)
+    }
+}
diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl
index cac8f34b0fa..bccffe39243 100644
--- a/compiler/rustc_metadata/messages.ftl
+++ b/compiler/rustc_metadata/messages.ftl
@@ -2,7 +2,7 @@ metadata_as_needed_compatibility =
     linking modifier `as-needed` is only compatible with `dylib` and `framework` linking kinds
 
 metadata_async_drop_types_in_dependency =
-    found async drop types in dependecy `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
+    found async drop types in dependency `{$extern_crate}`, but async_drop feature is disabled for `{$local_crate}`
     .help = if async drop type will be dropped in a crate without `feature(async_drop)`, sync Drop will be used
 
 metadata_bad_panic_strategy =
diff --git a/compiler/rustc_pattern_analysis/src/rustc.rs b/compiler/rustc_pattern_analysis/src/rustc.rs
index a89d01dcbbe..d9f1888bfd9 100644
--- a/compiler/rustc_pattern_analysis/src/rustc.rs
+++ b/compiler/rustc_pattern_analysis/src/rustc.rs
@@ -1,6 +1,5 @@
 use std::fmt;
 use std::iter::once;
-use std::ops::ControlFlow;
 
 use rustc_abi::{FIRST_VARIANT, FieldIdx, Integer, VariantIdx};
 use rustc_arena::DroplessArena;
@@ -12,8 +11,7 @@ use rustc_middle::mir::{self, Const};
 use rustc_middle::thir::{self, Pat, PatKind, PatRange, PatRangeBoundary};
 use rustc_middle::ty::layout::IntegerExt;
 use rustc_middle::ty::{
-    self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeSuperVisitable, TypeVisitable,
-    TypeVisitableExt, TypeVisitor, VariantDef,
+    self, FieldDef, OpaqueTypeKey, ScalarInt, Ty, TyCtxt, TypeVisitableExt, VariantDef,
 };
 use rustc_middle::{bug, span_bug};
 use rustc_session::lint;
@@ -137,22 +135,11 @@ impl<'p, 'tcx: 'p> RustcPatCtxt<'p, 'tcx> {
     /// Returns the hidden type corresponding to this key if the body under analysis is allowed to
     /// know it.
     fn reveal_opaque_key(&self, key: OpaqueTypeKey<'tcx>) -> Option<Ty<'tcx>> {
-        if let Some(hidden_ty) = self.typeck_results.concrete_opaque_types.get(&key.def_id) {
-            let ty = ty::EarlyBinder::bind(hidden_ty.ty).instantiate(self.tcx, key.args);
-            if ty.visit_with(&mut RecursiveOpaque { def_id: key.def_id.into() }).is_continue() {
-                Some(ty)
-            } else {
-                // HACK: We skip revealing opaque types which recursively expand
-                // to themselves. This is because we may infer hidden types like
-                // `Opaque<T> = Opaque<Opaque<T>>` or `Opaque<T> = Opaque<(T,)>`
-                // in hir typeck.
-                None
-            }
-        } else {
-            None
-        }
+        self.typeck_results
+            .concrete_opaque_types
+            .get(&key.def_id)
+            .map(|x| ty::EarlyBinder::bind(x.ty).instantiate(self.tcx, key.args))
     }
-
     // This can take a non-revealed `Ty` because it reveals opaques itself.
     pub fn is_uninhabited(&self, ty: Ty<'tcx>) -> bool {
         !ty.inhabited_predicate(self.tcx).apply_revealing_opaque(
@@ -1177,20 +1164,3 @@ fn detect_mixed_deref_pat_ctors<'p, 'tcx>(
     }
     Ok(())
 }
-
-struct RecursiveOpaque {
-    def_id: DefId,
-}
-impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for RecursiveOpaque {
-    type Result = ControlFlow<()>;
-
-    fn visit_ty(&mut self, t: Ty<'tcx>) -> Self::Result {
-        if let ty::Alias(ty::Opaque, alias_ty) = t.kind() {
-            if alias_ty.def_id == self.def_id {
-                return ControlFlow::Break(());
-            }
-        }
-
-        if t.has_opaque_types() { t.super_visit_with(self) } else { ControlFlow::Continue(()) }
-    }
-}
diff --git a/compiler/rustc_type_ir/src/region_kind.rs b/compiler/rustc_type_ir/src/region_kind.rs
index eae3213ead0..1b5d04e6025 100644
--- a/compiler/rustc_type_ir/src/region_kind.rs
+++ b/compiler/rustc_type_ir/src/region_kind.rs
@@ -193,7 +193,7 @@ impl<I: Interner> fmt::Debug for RegionKind<I> {
 
             ReVar(vid) => write!(f, "{vid:?}"),
 
-            RePlaceholder(placeholder) => write!(f, "{placeholder:?}"),
+            RePlaceholder(placeholder) => write!(f, "'{placeholder:?}"),
 
             // Use `'{erased}` as the output instead of `'erased` so that its more obviously distinct from
             // a `ReEarlyParam` named `'erased`. Technically that would print as `'erased/#IDX` so this is
diff --git a/src/doc/rustc-dev-guide/rust-version b/src/doc/rustc-dev-guide/rust-version
index 5e4266f61da..0d889a5d5b9 100644
--- a/src/doc/rustc-dev-guide/rust-version
+++ b/src/doc/rustc-dev-guide/rust-version
@@ -1 +1 @@
-414482f6a0d4e7290f614300581a0b55442552a3
+e42bbfe1f7c26f8760a99c4b1f27d33aba1040bb
diff --git a/src/doc/rustc-dev-guide/src/SUMMARY.md b/src/doc/rustc-dev-guide/src/SUMMARY.md
index 31119496e75..a7b76233d19 100644
--- a/src/doc/rustc-dev-guide/src/SUMMARY.md
+++ b/src/doc/rustc-dev-guide/src/SUMMARY.md
@@ -134,9 +134,9 @@
 
 - [Command-line arguments](./cli.md)
 - [rustc_driver and rustc_interface](./rustc-driver/intro.md)
+    - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md)
     - [Example: Type checking](./rustc-driver/interacting-with-the-ast.md)
     - [Example: Getting diagnostics](./rustc-driver/getting-diagnostics.md)
-    - [Remarks on perma-unstable features](./rustc-driver/remarks-on-perma-unstable-features.md)
 - [Errors and lints](diagnostics.md)
     - [Diagnostic and subdiagnostic structs](./diagnostics/diagnostic-structs.md)
     - [Translation](./diagnostics/translation.md)
diff --git a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md
index 513df1650c3..eeb2af5e6bc 100644
--- a/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md
+++ b/src/doc/rustc-dev-guide/src/backend/libs-and-metadata.md
@@ -28,8 +28,8 @@ format is specific to `rustc`, and may change over time. This file contains:
   [`-C embed-bitcode=no`][embed-bitcode] CLI option to improve compile times
   and reduce disk space if LTO is not needed.
 * `rustc` [metadata], in a file named `lib.rmeta`.
-* A symbol table, which is generally a list of symbols with offsets to the
-  object file that contain that symbol. This is pretty standard for archive
+* A symbol table, which is essentially a list of symbols with offsets to the
+  object files that contain that symbol. This is pretty standard for archive
   files.
 
 [archive file]: https://en.wikipedia.org/wiki/Ar_(Unix)
@@ -46,12 +46,11 @@ A `dylib` is a platform-specific shared library. It includes the `rustc`
 
 ### rmeta
 
-An `rmeta` file is custom binary format that contains the [metadata] for the
-crate. This file can be used for fast "checks" of a project by skipping all
-code generation (as is done with `cargo check`), collecting enough information
-for documentation (as is done with `cargo doc`), or for
-[pipelining](#pipelining). This file is created if the
-[`--emit=metadata`][emit] CLI option is used.
+An `rmeta` file is a custom binary format that contains the [metadata] for the
+crate. This file can be used for fast "checks" of a project by skipping all code
+generation (as is done with `cargo check`), collecting enough information for
+documentation (as is done with `cargo doc`), or for [pipelining](#pipelining).
+This file is created if the [`--emit=metadata`][emit] CLI option is used.
 
 `rmeta` files do not support linking, since they do not contain compiled
 object files.
@@ -60,8 +59,8 @@ object files.
 
 ## Metadata
 
-The metadata contains a wide swath of different elements. This guide will not
-go into detail of every field it contains. You are encouraged to browse the
+The metadata contains a wide swath of different elements. This guide will not go
+into detail about every field it contains. You are encouraged to browse the
 [`CrateRoot`] definition to get a sense of the different elements it contains.
 Everything about metadata encoding and decoding is in the [`rustc_metadata`]
 package.
@@ -122,9 +121,9 @@ much more.
 
 By default, all Rust symbols are mangled and incorporate the stable crate id.
 This allows multiple versions of the same crate to be included together. Cargo
-automatically generates `-C metadata` hashes based on a variety of factors,
-like the package version, source, and the target kind (a lib and test can have
-the same crate name, so they need to be disambiguated).
+automatically generates `-C metadata` hashes based on a variety of factors, like
+the package version, source, and target kind (a lib and test can have the same
+crate name, so they need to be disambiguated).
 
 [`StableCrateId`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html
 [`StableCrateId::new`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/def_id/struct.StableCrateId.html#method.new
@@ -154,7 +153,7 @@ will also look at the [sysroot] to find dependencies.
 
 As crates are loaded, they are kept in the [`CStore`] with the crate metadata
 wrapped in the [`CrateMetadata`] struct. After resolution and expansion, the
-`CStore` will make its way into the [`GlobalCtxt`] for the rest of
+`CStore` will make its way into the [`GlobalCtxt`] for the rest of the
 compilation.
 
 [name resolution]: ../name-resolution.md
diff --git a/src/doc/rustc-dev-guide/src/cli.md b/src/doc/rustc-dev-guide/src/cli.md
index 408ae207004..4c77007ea44 100644
--- a/src/doc/rustc-dev-guide/src/cli.md
+++ b/src/doc/rustc-dev-guide/src/cli.md
@@ -28,6 +28,6 @@ adding a new command-line argument.
   unstable-options` flag.
 
 [cli-docs]: https://doc.rust-lang.org/rustc/command-line-arguments.html
-[forge guide for new options]: https://forge.rust-lang.org/compiler/new_option.html
+[forge guide for new options]: https://forge.rust-lang.org/compiler/proposals-and-stabilization.html#compiler-flags
 [unstable book]: https://doc.rust-lang.org/nightly/unstable-book/
 [`parse_bool`]: https://github.com/rust-lang/rust/blob/e5335592e78354e33d798d20c04bcd677c1df62d/src/librustc_session/options.rs#L307-L313
diff --git a/src/doc/rustc-dev-guide/src/getting-started.md b/src/doc/rustc-dev-guide/src/getting-started.md
index 8bf14bef2a0..0e5b32a06f8 100644
--- a/src/doc/rustc-dev-guide/src/getting-started.md
+++ b/src/doc/rustc-dev-guide/src/getting-started.md
@@ -89,7 +89,7 @@ filtering the search to areas you're interested in. For example:
 Not all important or beginner work has issue labels.
 See below for how to find work that isn't labelled.
 
-[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+
+[help-wanted-search]: https://github.com/issues?q=is%3Aopen+is%3Aissue+org%3Arust-lang+no%3Aassignee+label%3AE-easy%2C%22good+first+issue%22%2Cgood-first-issue%2CE-medium%2CEasy%2CE-help-wanted%2CE-mentor+-label%3AS-blocked+-linked:pr+
 [Triage]: ./contributing.md#issue-triage
 
 ### Recurring work
diff --git a/src/doc/rustc-dev-guide/src/rustc-driver/intro.md b/src/doc/rustc-dev-guide/src/rustc-driver/intro.md
index 40500e6bc7a..a3684397b29 100644
--- a/src/doc/rustc-dev-guide/src/rustc-driver/intro.md
+++ b/src/doc/rustc-dev-guide/src/rustc-driver/intro.md
@@ -7,8 +7,8 @@ It acts as the glue for running the various phases of the compiler in the correc
 using the interface defined in the [`rustc_interface`] crate. Where possible, using [`rustc_driver`] rather than [`rustc_interface`] is recommended.
 
 The main entry point of [`rustc_driver`] is [`rustc_driver::run_compiler`][rd_rc].
-This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`][cb] and a couple of other optional options.
-[`Callbacks`][cb] is a `trait` that allows for custom compiler configuration,
+This builder accepts the same command-line args as rustc as well as an implementation of [`Callbacks`] and a couple of other optional options.
+[`Callbacks`] is a `trait` that allows for custom compiler configuration,
 as well as allowing custom code to run after different phases of the compilation.
 
 ## `rustc_interface`
@@ -33,14 +33,8 @@ specifically [`rustc_driver_impl::run_compiler`][rdi_rc]
 [`Compiler`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/struct.Compiler.html
 [`rustc_driver`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/
 [`rustc_interface`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/index.html
-[`Session`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_session/struct.Session.html
-[`SourceMap`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_span/source_map/struct.SourceMap.html
-[`TyCtxt`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/struct.TyCtxt.html
-[Appendix A]: appendix/stupid-stats.html
-[cb]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html
+[`Callbacks`]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/trait.Callbacks.html
 [example]: https://github.com/rust-lang/rustc-dev-guide/blob/master/examples/rustc-interface-example.rs
 [i_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_interface/interface/fn.run_compiler.html
 [rd_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver/fn.run_compiler.html
 [rdi_rc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_driver_impl/fn.run_compiler.html
-[stupid-stats]: https://github.com/nrc/stupid-stats
-[`nightly-rustc`]: https://doc.rust-lang.org/nightly/nightly-rustc/
diff --git a/tests/crashes/140823.rs b/tests/crashes/140823.rs
deleted file mode 100644
index ca2d683beed..00000000000
--- a/tests/crashes/140823.rs
+++ /dev/null
@@ -1,9 +0,0 @@
-//@ known-bug: #140823
-
-struct Container<T> {
-    data: T,
-}
-
-fn ice(callback: Box<dyn Fn(Container<&u8>)>) {
-    let fails: Box<dyn Fn(&Container<&u8>)> = callback;
-}
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.rs b/tests/ui/async-await/async-drop/dependency-dropped.rs
index c8670be4e8b..d7f415e19aa 100644
--- a/tests/ui/async-await/async-drop/dependency-dropped.rs
+++ b/tests/ui/async-await/async-drop/dependency-dropped.rs
@@ -5,7 +5,7 @@
 //@ edition:2021
 
 #![cfg_attr(with_feature, feature(async_drop))]
-//[without_feature]~^ WARN found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
+//[without_feature]~^ WARN found async drop types in dependency `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
 
 #![allow(incomplete_features)]
 
diff --git a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr
index 56e49568e10..96a4572055c 100644
--- a/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr
+++ b/tests/ui/async-await/async-drop/dependency-dropped.without_feature.stderr
@@ -1,4 +1,4 @@
-warning: found async drop types in dependecy `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
+warning: found async drop types in dependency `async_drop_dep`, but async_drop feature is disabled for `dependency_dropped`
   --> $DIR/dependency-dropped.rs:7:1
    |
 LL | #![cfg_attr(with_feature, feature(async_drop))]
diff --git a/tests/ui/fn/coerce-suggestion-infer-region.rs b/tests/ui/fn/coerce-suggestion-infer-region.rs
new file mode 100644
index 00000000000..7edb828c973
--- /dev/null
+++ b/tests/ui/fn/coerce-suggestion-infer-region.rs
@@ -0,0 +1,26 @@
+//! Functions with a mismatch between the expected and found type where the difference is a
+//! reference may trigger analysis for additional help. In this test the expected type will be
+//! &'a Container<&'a u8> and the found type will be Container<&'?0 u8>.
+//!
+//! This test exercises a scenario where the found type being analyzed contains an inference region
+//! variable ('?0). This cannot be used in comparisons because the variable no longer exists by the
+//! time the later analysis is performed.
+//!
+//! This is a regression test of #140823
+
+trait MyFn<P> {}
+
+struct Container<T> {
+    data: T,
+}
+
+struct Desugared {
+    callback: Box<dyn for<'a> MyFn<&'a Container<&'a u8>>>,
+}
+
+fn test(callback: Box<dyn for<'a> MyFn<Container<&'a u8>>>) -> Desugared {
+    Desugared { callback }
+    //~^ ERROR mismatched types
+}
+
+fn main() {}
diff --git a/tests/ui/fn/coerce-suggestion-infer-region.stderr b/tests/ui/fn/coerce-suggestion-infer-region.stderr
new file mode 100644
index 00000000000..9dd0fcf76ce
--- /dev/null
+++ b/tests/ui/fn/coerce-suggestion-infer-region.stderr
@@ -0,0 +1,12 @@
+error[E0308]: mismatched types
+  --> $DIR/coerce-suggestion-infer-region.rs:22:17
+   |
+LL |     Desugared { callback }
+   |                 ^^^^^^^^ expected `Box<dyn MyFn<&Container<&u8>>>`, found `Box<dyn MyFn<Container<&u8>>>`
+   |
+   = note: expected struct `Box<(dyn for<'a> MyFn<&'a Container<&'a u8>> + 'static)>`
+              found struct `Box<(dyn for<'a> MyFn<Container<&'a u8>> + 'static)>`
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0308`.
diff --git a/tests/ui/impl-trait/issues/issue-100075-2.stderr b/tests/ui/impl-trait/issues/issue-100075-2.stderr
index b3b69677507..554c3ea3433 100644
--- a/tests/ui/impl-trait/issues/issue-100075-2.stderr
+++ b/tests/ui/impl-trait/issues/issue-100075-2.stderr
@@ -1,3 +1,9 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/issue-100075-2.rs:1:23
+   |
+LL | fn opaque<T>(t: T) -> impl Sized {
+   |                       ^^^^^^^^^^
+
 warning: function cannot return without recursing
   --> $DIR/issue-100075-2.rs:1:1
    |
@@ -10,15 +16,6 @@ LL |     opaque(Some(t))
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error[E0720]: cannot resolve opaque type
-  --> $DIR/issue-100075-2.rs:1:23
-   |
-LL | fn opaque<T>(t: T) -> impl Sized {
-   |                       ^^^^^^^^^^ recursive opaque type
-...
-LL |     opaque(Some(t))
-   |     --------------- returning here with type `impl Sized`
-
 error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/issues/issue-100075.stderr b/tests/ui/impl-trait/issues/issue-100075.stderr
index 75963489236..bca2874b2b4 100644
--- a/tests/ui/impl-trait/issues/issue-100075.stderr
+++ b/tests/ui/impl-trait/issues/issue-100075.stderr
@@ -2,10 +2,7 @@ error[E0720]: cannot resolve opaque type
   --> $DIR/issue-100075.rs:13:37
    |
 LL | fn _g<T>(t: &'static T) -> &'static impl Marker {
-   |                                     ^^^^^^^^^^^ recursive opaque type
-...
-LL |         return _g(t);
-   |                ----- returning here with type `&impl Marker`
+   |                                     ^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/ui/impl-trait/issues/issue-103599.rs b/tests/ui/impl-trait/issues/issue-103599.rs
index 62741a7454c..e674ce3cbdf 100644
--- a/tests/ui/impl-trait/issues/issue-103599.rs
+++ b/tests/ui/impl-trait/issues/issue-103599.rs
@@ -1,9 +1,8 @@
-//@ check-pass
-
 trait T {}
 
 fn wrap(x: impl T) -> impl T {
-    //~^ WARN function cannot return without recursing
+    //~^ ERROR cannot resolve opaque type
+    //~| WARN function cannot return without recursing
     wrap(wrap(x))
 }
 
diff --git a/tests/ui/impl-trait/issues/issue-103599.stderr b/tests/ui/impl-trait/issues/issue-103599.stderr
index 82038c1dceb..9878b12044f 100644
--- a/tests/ui/impl-trait/issues/issue-103599.stderr
+++ b/tests/ui/impl-trait/issues/issue-103599.stderr
@@ -1,14 +1,21 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/issue-103599.rs:3:23
+   |
+LL | fn wrap(x: impl T) -> impl T {
+   |                       ^^^^^^
+
 warning: function cannot return without recursing
-  --> $DIR/issue-103599.rs:5:1
+  --> $DIR/issue-103599.rs:3:1
    |
 LL | fn wrap(x: impl T) -> impl T {
    | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
-LL |
+...
 LL |     wrap(wrap(x))
    |          ------- recursive call site
    |
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-warning: 1 warning emitted
+error: aborting due to 1 previous error; 1 warning emitted
 
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/issues/issue-87450.rs b/tests/ui/impl-trait/issues/issue-87450.rs
index 983ef7cfbe0..5a7759af111 100644
--- a/tests/ui/impl-trait/issues/issue-87450.rs
+++ b/tests/ui/impl-trait/issues/issue-87450.rs
@@ -3,8 +3,8 @@ fn bar() -> impl Fn() {
 }
 
 fn foo() -> impl Fn() {
-    //~^ WARNING 5:1: 5:22: function cannot return without recursing [unconditional_recursion]
-    //~| ERROR 5:13: 5:22: cannot resolve opaque type [E0720]
+    //~^ WARN function cannot return without recursing
+    //~| ERROR cannot resolve opaque type
     wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
 }
 
diff --git a/tests/ui/impl-trait/issues/issue-87450.stderr b/tests/ui/impl-trait/issues/issue-87450.stderr
index 9567e09651d..f0f8b5859c0 100644
--- a/tests/ui/impl-trait/issues/issue-87450.stderr
+++ b/tests/ui/impl-trait/issues/issue-87450.stderr
@@ -1,3 +1,9 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/issue-87450.rs:5:13
+   |
+LL | fn foo() -> impl Fn() {
+   |             ^^^^^^^^^
+
 warning: function cannot return without recursing
   --> $DIR/issue-87450.rs:5:1
    |
@@ -10,18 +16,6 @@ LL |     wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
    = help: a `loop` may express intention better if this is on purpose
    = note: `#[warn(unconditional_recursion)]` on by default
 
-error[E0720]: cannot resolve opaque type
-  --> $DIR/issue-87450.rs:5:13
-   |
-LL | fn foo() -> impl Fn() {
-   |             ^^^^^^^^^ recursive opaque type
-...
-LL |     wrap(wrap(wrap(wrap(wrap(wrap(wrap(foo())))))))
-   |     ----------------------------------------------- returning here with type `impl Fn()`
-...
-LL | fn wrap(f: impl Fn()) -> impl Fn() {
-   |                          --------- returning this opaque type `impl Fn()`
-
 error: aborting due to 1 previous error; 1 warning emitted
 
 For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
index 2d2731e4368..af84375c747 100644
--- a/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
+++ b/tests/ui/impl-trait/recursive-impl-trait-type-indirect.stderr
@@ -2,112 +2,67 @@ error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:6:22
    |
 LL | fn option(i: i32) -> impl Sized {
-   |                      ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     if i < 0 { None } else { Some((option(i - 1), i)) }
-   |                ----          ------------------------ returning here with type `Option<(impl Sized, i32)>`
-   |                |
-   |                returning here with type `Option<(impl Sized, i32)>`
+   |                      ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:11:15
    |
 LL | fn tuple() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (tuple(),)
-   |     ---------- returning here with type `(impl Sized,)`
+   |               ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:16:15
    |
 LL | fn array() -> impl Sized {
-   |               ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     [array()]
-   |     --------- returning here with type `[impl Sized; 1]`
+   |               ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:21:13
    |
 LL | fn ptr() -> impl Sized {
-   |             ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     &ptr() as *const _
-   |     ------------------ returning here with type `*const impl Sized`
+   |             ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:26:16
    |
 LL | fn fn_ptr() -> impl Sized {
-   |                ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     fn_ptr as fn() -> _
-   |     ------------------- returning here with type `fn() -> impl Sized`
+   |                ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:31:25
    |
-LL |   fn closure_capture() -> impl Sized {
-   |                           ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         x;
-   | |         - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:34:5: 34:12}`
+LL | fn closure_capture() -> impl Sized {
+   |                         ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:39:29
    |
-LL |   fn closure_ref_capture() -> impl Sized {
-   |                               ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         &x;
-   | |          - closure captures itself here
-LL | |     }
-   | |_____- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:42:5: 42:12}`
+LL | fn closure_ref_capture() -> impl Sized {
+   |                             ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:47:21
    |
 LL | fn closure_sig() -> impl Sized {
-   |                     ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || closure_sig()
-   |     ---------------- returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:49:5: 49:7}`
+   |                     ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:52:23
    |
 LL | fn coroutine_sig() -> impl Sized {
-   |                       ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     || coroutine_sig()
-   |     ------------------ returning here with type `{closure@$DIR/recursive-impl-trait-type-indirect.rs:54:5: 54:7}`
+   |                       ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:57:27
    |
-LL |   fn coroutine_capture() -> impl Sized {
-   |                             ^^^^^^^^^^ recursive opaque type
-...
-LL | /     move || {
-LL | |         yield;
-LL | |         x;
-   | |         - coroutine captures itself here
-LL | |     }
-   | |_____- returning here with type `{coroutine@$DIR/recursive-impl-trait-type-indirect.rs:62:5: 62:12}`
+LL | fn coroutine_capture() -> impl Sized {
+   |                           ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:68:35
    |
 LL | fn substs_change<T: 'static>() -> impl Sized {
-   |                                   ^^^^^^^^^^ recursive opaque type
-LL |
-LL |     (substs_change::<&T>(),)
-   |     ------------------------ returning here with type `(impl Sized,)`
+   |                                   ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-impl-trait-type-indirect.rs:78:26
diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr b/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr
index 42dbc7c9160..080c3284641 100644
--- a/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr
+++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.current.stderr
@@ -1,56 +1,21 @@
-warning: function cannot return without recursing
-  --> $DIR/recursive-in-exhaustiveness.rs:17:1
+error[E0720]: cannot resolve opaque type
+  --> $DIR/recursive-in-exhaustiveness.rs:17:22
    |
 LL | fn build<T>(x: T) -> impl Sized {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
-LL |
-LL |     let (x,) = (build(x),);
-   |                 -------- recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
-   = note: `#[warn(unconditional_recursion)]` on by default
-
-warning: function cannot return without recursing
-  --> $DIR/recursive-in-exhaustiveness.rs:27:1
-   |
-LL | fn build2<T>(x: T) -> impl Sized {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
-...
-LL |     let (x,) = (build2(x),);
-   |                 --------- recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
+   |                      ^^^^^^^^^^
 
 error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-in-exhaustiveness.rs:27:23
    |
 LL | fn build2<T>(x: T) -> impl Sized {
-   |                       ^^^^^^^^^^ recursive opaque type
-...
-LL |     (build2(x),)
-   |     ------------ returning here with type `(impl Sized,)`
+   |                       ^^^^^^^^^^
 
-warning: function cannot return without recursing
-  --> $DIR/recursive-in-exhaustiveness.rs:40:1
-   |
-LL | fn build3<T>(x: T) -> impl Sized {
-   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot return without recursing
-LL |
-LL |     let (x,) = (build3((x,)),);
-   |                 ------------ recursive call site
-   |
-   = help: a `loop` may express intention better if this is on purpose
-
-error[E0792]: expected generic type parameter, found `(T,)`
-  --> $DIR/recursive-in-exhaustiveness.rs:49:5
+error[E0720]: cannot resolve opaque type
+  --> $DIR/recursive-in-exhaustiveness.rs:39:23
    |
 LL | fn build3<T>(x: T) -> impl Sized {
-   |           - this generic parameter must be used with a generic type parameter
-...
-LL |     build3(x)
-   |     ^^^^^^^^^
+   |                       ^^^^^^^^^^
 
-error: aborting due to 2 previous errors; 3 warnings emitted
+error: aborting due to 3 previous errors
 
-Some errors have detailed explanations: E0720, E0792.
-For more information about an error, try `rustc --explain E0720`.
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr b/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
index 4c3d5aa8fb8..a3609b93cb3 100644
--- a/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
+++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.next.stderr
@@ -5,19 +5,19 @@ LL |     let (x,) = (build(x),);
    |                 ^^^^^^^^ cannot satisfy `impl Sized == _`
 
 error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:31:6
+  --> $DIR/recursive-in-exhaustiveness.rs:30:6
    |
 LL |     (build2(x),)
    |      ^^^^^^^^^ types differ
 
 error[E0271]: type mismatch resolving `build2<(_,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:31:5
+  --> $DIR/recursive-in-exhaustiveness.rs:30:5
    |
 LL |     (build2(x),)
    |     ^^^^^^^^^^^^ types differ
 
 error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
-  --> $DIR/recursive-in-exhaustiveness.rs:31:5
+  --> $DIR/recursive-in-exhaustiveness.rs:30:5
    |
 LL |     (build2(x),)
    |     ^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -26,13 +26,13 @@ LL |     (build2(x),)
    = note: tuples must have a statically known size to be initialized
 
 error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:42:17
+  --> $DIR/recursive-in-exhaustiveness.rs:41:17
    |
 LL |     let (x,) = (build3((x,)),);
    |                 ^^^^^^^^^^^^ types differ
 
 error[E0277]: the size for values of type `(impl Sized,)` cannot be known at compilation time
-  --> $DIR/recursive-in-exhaustiveness.rs:42:16
+  --> $DIR/recursive-in-exhaustiveness.rs:41:16
    |
 LL |     let (x,) = (build3((x,)),);
    |                ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -41,7 +41,7 @@ LL |     let (x,) = (build3((x,)),);
    = note: tuples must have a statically known size to be initialized
 
 error[E0308]: mismatched types
-  --> $DIR/recursive-in-exhaustiveness.rs:42:16
+  --> $DIR/recursive-in-exhaustiveness.rs:41:16
    |
 LL | fn build3<T>(x: T) -> impl Sized {
    |                       ---------- the found opaque type
@@ -53,7 +53,7 @@ LL |     let (x,) = (build3((x,)),);
              found tuple `(impl Sized,)`
 
 error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:42:17
+  --> $DIR/recursive-in-exhaustiveness.rs:41:17
    |
 LL |     let (x,) = (build3((x,)),);
    |                 ^^^^^^^^^^^^ types differ
@@ -61,13 +61,13 @@ LL |     let (x,) = (build3((x,)),);
    = note: the return type of a function must have a statically known size
 
 error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:42:16
+  --> $DIR/recursive-in-exhaustiveness.rs:41:16
    |
 LL |     let (x,) = (build3((x,)),);
    |                ^^^^^^^^^^^^^^^ types differ
 
 error[E0271]: type mismatch resolving `build3<(T,)>::{opaque#0} normalizes-to _`
-  --> $DIR/recursive-in-exhaustiveness.rs:42:17
+  --> $DIR/recursive-in-exhaustiveness.rs:41:17
    |
 LL |     let (x,) = (build3((x,)),);
    |                 ^^^^^^^^^^^^ types differ
diff --git a/tests/ui/impl-trait/recursive-in-exhaustiveness.rs b/tests/ui/impl-trait/recursive-in-exhaustiveness.rs
index 58944533686..fa8fa0e8174 100644
--- a/tests/ui/impl-trait/recursive-in-exhaustiveness.rs
+++ b/tests/ui/impl-trait/recursive-in-exhaustiveness.rs
@@ -15,7 +15,7 @@
 // We unfortunately accept this today, and due to how opaque type relating is implemented
 // in the NLL type relation, this defines `Opaque<T> = T`.
 fn build<T>(x: T) -> impl Sized {
-    //[current]~^ WARN function cannot return without recursing
+    //[current]~^ ERROR cannot resolve opaque type
     let (x,) = (build(x),);
     //[next]~^ ERROR type annotations needed
     build(x)
@@ -26,7 +26,6 @@ fn build<T>(x: T) -> impl Sized {
 // Not allowed today. Detected as recursive.
 fn build2<T>(x: T) -> impl Sized {
     //[current]~^ ERROR cannot resolve opaque type
-    //[current]~| WARN function cannot return without recursing
     let (x,) = (build2(x),);
     (build2(x),)
     //[next]~^ ERROR type mismatch resolving
@@ -38,7 +37,7 @@ fn build2<T>(x: T) -> impl Sized {
 //
 // Not allowed today. Detected as not defining.
 fn build3<T>(x: T) -> impl Sized {
-    //[current]~^ WARN function cannot return without recursing
+    //[current]~^ ERROR cannot resolve opaque type
     let (x,) = (build3((x,)),);
     //[next]~^ ERROR type mismatch resolving
     //[next]~| ERROR type mismatch resolving
@@ -47,7 +46,6 @@ fn build3<T>(x: T) -> impl Sized {
     //[next]~| ERROR the size for values of type
     //[next]~| ERROR mismatched types
     build3(x)
-    //[current]~^ ERROR expected generic type parameter, found `(T,)`
 }
 
 fn main() {}
diff --git a/tests/ui/pattern/rfc-3637-guard-patterns/only-gather-locals-once.rs b/tests/ui/pattern/rfc-3637-guard-patterns/only-gather-locals-once.rs
new file mode 100644
index 00000000000..7bb39ca7bb9
--- /dev/null
+++ b/tests/ui/pattern/rfc-3637-guard-patterns/only-gather-locals-once.rs
@@ -0,0 +1,15 @@
+//@ check-pass
+//! Test that `GatherLocalsVisitor` only visits expressions in guard patterns when checking the
+//! expressions, and not a second time when visiting the pattern. If locals are declared inside the
+//! the guard expression, it would ICE if visited twice ("evaluated expression more than once").
+
+#![feature(guard_patterns)]
+#![expect(incomplete_features)]
+
+fn main() {
+    match (0,) {
+        // FIXME(guard_patterns): liveness lints don't work yet; this will ICE without the `_`.
+        (_ if { let _x = false; _x },) => {}
+        _ => {}
+    }
+}
diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
index ef6871bec7c..0aaee5d1764 100644
--- a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
+++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.rs
@@ -1,10 +1,10 @@
 #![feature(type_alias_impl_trait)]
 
 type T = impl Copy;
-//~^ ERROR cannot resolve opaque type
 
 #[define_opaque(T)]
 fn foo() -> T {
+    //~^ ERROR cannot resolve opaque type
     None::<&'static T>
 }
 
diff --git a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr
index d820df472f9..426a6c29fff 100644
--- a/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr
+++ b/tests/ui/type-alias-impl-trait/infinite-cycle-involving-weak.stderr
@@ -1,8 +1,8 @@
 error[E0720]: cannot resolve opaque type
-  --> $DIR/infinite-cycle-involving-weak.rs:3:10
+  --> $DIR/infinite-cycle-involving-weak.rs:6:13
    |
-LL | type T = impl Copy;
-   |          ^^^^^^^^^ cannot resolve opaque type
+LL | fn foo() -> T {
+   |             ^
 
 error: aborting due to 1 previous error
 
diff --git a/tests/crashes/139817.rs b/tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.rs
index d439ed4cacb..f4e2cb0c037 100644
--- a/tests/crashes/139817.rs
+++ b/tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.rs
@@ -1,8 +1,12 @@
-//@ known-bug: #139817
+#![feature(type_alias_impl_trait)]
+
 fn enum_upvar() {
     type T = impl Copy;
     let foo: T = Some((42, std::marker::PhantomData::<T>));
     let x = move || match foo {
         None => (),
+        //~^ ERROR cannot resolve opaque type
     };
 }
+
+fn main() {}
diff --git a/tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.stderr b/tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.stderr
new file mode 100644
index 00000000000..2bfce2d63a8
--- /dev/null
+++ b/tests/ui/type-alias-impl-trait/match-upvar-discriminant-of-opaque.stderr
@@ -0,0 +1,9 @@
+error[E0720]: cannot resolve opaque type
+  --> $DIR/match-upvar-discriminant-of-opaque.rs:7:9
+   |
+LL |         None => (),
+   |         ^^^^
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
index 94597adfed0..fe354cc6545 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.rs
@@ -13,7 +13,7 @@ pub fn add(
     n: Diff,
     m: Diff,
 ) -> Diff {
-    //~^ ERROR concrete type differs
+    //~^ ERROR cannot resolve opaque type
     move |x: usize| m(n(x))
 }
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
index 59ff9917612..847f1cc6c2e 100644
--- a/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-fn-tait.stderr
@@ -1,14 +1,9 @@
-error: concrete type differs from previous defining opaque type use
+error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-fn-tait.rs:15:6
    |
 LL | ) -> Diff {
-   |      ^^^^ expected `{closure@$DIR/recursive-fn-tait.rs:8:5: 8:16}`, got `{closure@$DIR/recursive-fn-tait.rs:17:5: 17:20}`
-   |
-note: previous use here
-  --> $DIR/recursive-fn-tait.rs:7:18
-   |
-LL | pub fn lift() -> Diff {
-   |                  ^^^^
+   |      ^^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
index 858f2a2feb6..7803b3b78db 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.rs
@@ -13,7 +13,7 @@ fn transform<S>() -> impl std::fmt::Display {
 }
 #[define_opaque(Op)]
 fn bad() -> Op {
-    //~^ ERROR concrete type differs from previous defining opaque type use
+    //~^ ERROR cannot resolve opaque type
     transform::<Op>()
 }
 
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
index e527b5bc7f8..837df7f5d43 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn-2.stderr
@@ -1,14 +1,9 @@
-error: concrete type differs from previous defining opaque type use
+error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-tait-conflicting-defn-2.rs:15:13
    |
 LL | fn bad() -> Op {
-   |             ^^ expected `&&str`, got `impl std::fmt::Display`
-   |
-note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn-2.rs:7:13
-   |
-LL | fn foo() -> Op {
    |             ^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0720`.
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
index 90581a98a34..d66ceda5234 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.rs
@@ -23,7 +23,7 @@ pub fn test() -> TestImpl {
 
 #[define_opaque(TestImpl)]
 fn make_option2() -> Option<TestImpl> {
-    //~^ ERROR concrete type differs from previous defining opaque type use
+    //~^ ERROR cannot resolve opaque type
     let inner = make_option().unwrap();
     Some(B { inner })
 }
diff --git a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
index 256f13b6221..c7a3381d615 100644
--- a/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
+++ b/tests/ui/type-alias-impl-trait/recursive-tait-conflicting-defn.stderr
@@ -1,14 +1,9 @@
-error: concrete type differs from previous defining opaque type use
+error[E0720]: cannot resolve opaque type
   --> $DIR/recursive-tait-conflicting-defn.rs:25:22
    |
 LL | fn make_option2() -> Option<TestImpl> {
-   |                      ^^^^^^^^^^^^^^^^ expected `A`, got `B<TestImpl>`
-   |
-note: previous use here
-  --> $DIR/recursive-tait-conflicting-defn.rs:20:18
-   |
-LL | pub fn test() -> TestImpl {
-   |                  ^^^^^^^^
+   |                      ^^^^^^^^^^^^^^^^
 
 error: aborting due to 1 previous error
 
+For more information about this error, try `rustc --explain E0720`.