about summary refs log tree commit diff
path: root/compiler/rustc_hir_analysis/src
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_hir_analysis/src')
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs118
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs113
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs32
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs58
-rw-r--r--compiler/rustc_hir_analysis/src/constrained_generic_params.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/errors.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs56
-rw-r--r--compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs14
-rw-r--r--compiler/rustc_hir_analysis/src/hir_wf_check.rs11
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs21
-rw-r--r--compiler/rustc_hir_analysis/src/outlives/utils.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs10
19 files changed, 293 insertions, 187 deletions
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index a0798656763..18ef00dc8b1 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -397,8 +397,11 @@ fn best_definition_site_of_opaque<'tcx>(
                 return ControlFlow::Continue(());
             }
 
-            if let Some(hidden_ty) =
-                self.tcx.mir_borrowck(item_def_id).concrete_opaque_types.get(&self.opaque_def_id)
+            if let Some(hidden_ty) = self
+                .tcx
+                .mir_borrowck(item_def_id)
+                .ok()
+                .and_then(|opaque_types| opaque_types.0.get(&self.opaque_def_id))
             {
                 ControlFlow::Break((hidden_ty.span, item_def_id))
             } else {
@@ -413,9 +416,6 @@ fn best_definition_site_of_opaque<'tcx>(
             self.tcx
         }
         fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) -> Self::Result {
-            if let hir::ExprKind::Closure(closure) = ex.kind {
-                self.check(closure.def_id)?;
-            }
             intravisit::walk_expr(self, ex)
         }
         fn visit_item(&mut self, it: &'tcx hir::Item<'tcx>) -> Self::Result {
@@ -741,10 +741,6 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
 
             for &assoc_item in assoc_items.in_definition_order() {
                 match assoc_item.kind {
-                    ty::AssocKind::Fn => {
-                        let abi = tcx.fn_sig(assoc_item.def_id).skip_binder().abi();
-                        forbid_intrinsic_abi(tcx, assoc_item.ident(tcx).span, abi);
-                    }
                     ty::AssocKind::Type if assoc_item.defaultness(tcx).has_value() => {
                         let trait_args = GenericArgs::identity_for_item(tcx, def_id);
                         let _: Result<_, rustc_errors::ErrorGuaranteed> = check_type_bounds(
@@ -788,65 +784,59 @@ pub(crate) fn check_item_type(tcx: TyCtxt<'_>, def_id: LocalDefId) {
             };
             check_abi(tcx, it.span, abi);
 
-            match abi {
-                ExternAbi::RustIntrinsic => {
-                    for item in items {
-                        intrinsic::check_intrinsic_type(
-                            tcx,
-                            item.id.owner_id.def_id,
-                            item.span,
-                            item.ident.name,
-                            abi,
-                        );
-                    }
+            for item in items {
+                let def_id = item.id.owner_id.def_id;
+
+                if tcx.has_attr(def_id, sym::rustc_intrinsic) {
+                    intrinsic::check_intrinsic_type(
+                        tcx,
+                        item.id.owner_id.def_id,
+                        item.span,
+                        item.ident.name,
+                        abi,
+                    );
                 }
 
-                _ => {
-                    for item in items {
-                        let def_id = item.id.owner_id.def_id;
-                        let generics = tcx.generics_of(def_id);
-                        let own_counts = generics.own_counts();
-                        if generics.own_params.len() - own_counts.lifetimes != 0 {
-                            let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts)
-                            {
-                                (_, 0) => ("type", "types", Some("u32")),
-                                // We don't specify an example value, because we can't generate
-                                // a valid value for any type.
-                                (0, _) => ("const", "consts", None),
-                                _ => ("type or const", "types or consts", None),
-                            };
-                            struct_span_code_err!(
-                                tcx.dcx(),
-                                item.span,
-                                E0044,
-                                "foreign items may not have {kinds} parameters",
-                            )
-                            .with_span_label(item.span, format!("can't have {kinds} parameters"))
-                            .with_help(
-                                // FIXME: once we start storing spans for type arguments, turn this
-                                // into a suggestion.
-                                format!(
-                                    "replace the {} parameters with concrete {}{}",
-                                    kinds,
-                                    kinds_pl,
-                                    egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
-                                ),
-                            )
-                            .emit();
-                        }
+                let generics = tcx.generics_of(def_id);
+                let own_counts = generics.own_counts();
+                if generics.own_params.len() - own_counts.lifetimes != 0 {
+                    let (kinds, kinds_pl, egs) = match (own_counts.types, own_counts.consts) {
+                        (_, 0) => ("type", "types", Some("u32")),
+                        // We don't specify an example value, because we can't generate
+                        // a valid value for any type.
+                        (0, _) => ("const", "consts", None),
+                        _ => ("type or const", "types or consts", None),
+                    };
+                    struct_span_code_err!(
+                        tcx.dcx(),
+                        item.span,
+                        E0044,
+                        "foreign items may not have {kinds} parameters",
+                    )
+                    .with_span_label(item.span, format!("can't have {kinds} parameters"))
+                    .with_help(
+                        // FIXME: once we start storing spans for type arguments, turn this
+                        // into a suggestion.
+                        format!(
+                            "replace the {} parameters with concrete {}{}",
+                            kinds,
+                            kinds_pl,
+                            egs.map(|egs| format!(" like `{egs}`")).unwrap_or_default(),
+                        ),
+                    )
+                    .emit();
+                }
 
-                        let item = tcx.hir_foreign_item(item.id);
-                        match &item.kind {
-                            hir::ForeignItemKind::Fn(sig, _, _) => {
-                                require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
-                            }
-                            hir::ForeignItemKind::Static(..) => {
-                                check_static_inhabited(tcx, def_id);
-                                check_static_linkage(tcx, def_id);
-                            }
-                            _ => {}
-                        }
+                let item = tcx.hir_foreign_item(item.id);
+                match &item.kind {
+                    hir::ForeignItemKind::Fn(sig, _, _) => {
+                        require_c_abi_if_c_variadic(tcx, sig.decl, abi, item.span);
+                    }
+                    hir::ForeignItemKind::Static(..) => {
+                        check_static_inhabited(tcx, def_id);
+                        check_static_linkage(tcx, def_id);
                     }
+                    _ => {}
                 }
             }
         }
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 5e68bb31001..32a8f101849 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -442,7 +442,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for RemapLateParam<'tcx> {
     }
 
     fn fold_region(&mut self, r: ty::Region<'tcx>) -> ty::Region<'tcx> {
-        if let ty::ReLateParam(fr) = *r {
+        if let ty::ReLateParam(fr) = r.kind() {
             ty::Region::new_late_param(
                 self.tcx,
                 fr.scope,
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 42d785c8dd0..0bf9e127989 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -1,4 +1,4 @@
-//! Type-checking for the rust-intrinsic intrinsics that the compiler exposes.
+//! Type-checking for the `#[rustc_intrinsic]` intrinsics that the compiler exposes.
 
 use rustc_abi::ExternAbi;
 use rustc_errors::codes::*;
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 7c5d7b33a34..30921b6f055 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -137,15 +137,6 @@ fn get_owner_return_paths(
     })
 }
 
-/// Forbid defining intrinsics in Rust code,
-/// as they must always be defined by the compiler.
-// FIXME: Move this to a more appropriate place.
-pub fn forbid_intrinsic_abi(tcx: TyCtxt<'_>, sp: Span, abi: ExternAbi) {
-    if let ExternAbi::RustIntrinsic = abi {
-        tcx.dcx().span_err(sp, "intrinsic must be in `extern \"rust-intrinsic\" { ... }` block");
-    }
-}
-
 pub(super) fn maybe_check_static_with_link_section(tcx: TyCtxt<'_>, id: LocalDefId) {
     // Only restricted on wasm target for now
     if !tcx.sess.target.is_like_wasm {
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index cf66ab708bb..7cb31a64e13 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -8,6 +8,7 @@
 
 use std::mem;
 
+use rustc_data_structures::fx::FxHashMap;
 use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
@@ -44,6 +45,8 @@ struct ScopeResolutionVisitor<'tcx> {
     scope_tree: ScopeTree,
 
     cx: Context,
+
+    extended_super_lets: FxHashMap<hir::ItemLocalId, Option<Scope>>,
 }
 
 /// Records the lifetime of a local variable as `cx.var_parent`
@@ -214,18 +217,29 @@ fn resolve_stmt<'tcx>(visitor: &mut ScopeResolutionVisitor<'tcx>, stmt: &'tcx hi
     let stmt_id = stmt.hir_id.local_id;
     debug!("resolve_stmt(stmt.id={:?})", stmt_id);
 
-    // Every statement will clean up the temporaries created during
-    // execution of that statement. Therefore each statement has an
-    // associated destruction scope that represents the scope of the
-    // statement plus its destructors, and thus the scope for which
-    // regions referenced by the destructors need to survive.
+    if let hir::StmtKind::Let(LetStmt { super_: Some(_), .. }) = stmt.kind {
+        // `super let` statement does not start a new scope, such that
+        //
+        //     { super let x = identity(&temp()); &x }.method();
+        //
+        // behaves exactly as
+        //
+        //     (&identity(&temp()).method();
+        intravisit::walk_stmt(visitor, stmt);
+    } else {
+        // Every statement will clean up the temporaries created during
+        // execution of that statement. Therefore each statement has an
+        // associated destruction scope that represents the scope of the
+        // statement plus its destructors, and thus the scope for which
+        // regions referenced by the destructors need to survive.
 
-    let prev_parent = visitor.cx.parent;
-    visitor.enter_node_scope_with_dtor(stmt_id, true);
+        let prev_parent = visitor.cx.parent;
+        visitor.enter_node_scope_with_dtor(stmt_id, true);
 
-    intravisit::walk_stmt(visitor, stmt);
+        intravisit::walk_stmt(visitor, stmt);
 
-    visitor.cx.parent = prev_parent;
+        visitor.cx.parent = prev_parent;
+    }
 }
 
 fn resolve_expr<'tcx>(
@@ -446,14 +460,11 @@ fn resolve_expr<'tcx>(
         // Mark this expr's scope and all parent scopes as containing `yield`.
         let mut scope = Scope { local_id: expr.hir_id.local_id, data: ScopeData::Node };
         loop {
-            let span = match expr.kind {
-                hir::ExprKind::Yield(expr, hir::YieldSource::Await { .. }) => {
-                    expr.span.shrink_to_hi().to(expr.span)
-                }
-                _ => expr.span,
+            let data = YieldData {
+                span: expr.span,
+                expr_and_pat_count: visitor.expr_and_pat_count,
+                source: *source,
             };
-            let data =
-                YieldData { span, expr_and_pat_count: visitor.expr_and_pat_count, source: *source };
             match visitor.scope_tree.yield_in_scope.get_mut(&scope) {
                 Some(yields) => yields.push(data),
                 None => {
@@ -481,14 +492,19 @@ fn resolve_expr<'tcx>(
     visitor.cx = prev_cx;
 }
 
+#[derive(Copy, Clone, PartialEq, Eq, Debug)]
+enum LetKind {
+    Regular,
+    Super,
+}
+
 fn resolve_local<'tcx>(
     visitor: &mut ScopeResolutionVisitor<'tcx>,
     pat: Option<&'tcx hir::Pat<'tcx>>,
     init: Option<&'tcx hir::Expr<'tcx>>,
+    let_kind: LetKind,
 ) {
-    debug!("resolve_local(pat={:?}, init={:?})", pat, init);
-
-    let blk_scope = visitor.cx.var_parent;
+    debug!("resolve_local(pat={:?}, init={:?}, let_kind={:?})", pat, init, let_kind);
 
     // As an exception to the normal rules governing temporary
     // lifetimes, initializers in a let have a temporary lifetime
@@ -546,14 +562,50 @@ fn resolve_local<'tcx>(
     // A, but the inner rvalues `a()` and `b()` have an extended lifetime
     // due to rule C.
 
+    if let_kind == LetKind::Super {
+        if let Some(scope) = visitor.extended_super_lets.remove(&pat.unwrap().hir_id.local_id) {
+            // This expression was lifetime-extended by a parent let binding. E.g.
+            //
+            //     let a = {
+            //         super let b = temp();
+            //         &b
+            //     };
+            //
+            // (Which needs to behave exactly as: let a = &temp();)
+            //
+            // Processing of `let a` will have already decided to extend the lifetime of this
+            // `super let` to its own var_scope. We use that scope.
+            visitor.cx.var_parent = scope;
+        } else {
+            // This `super let` is not subject to lifetime extension from a parent let binding. E.g.
+            //
+            //     identity({ super let x = temp(); &x }).method();
+            //
+            // (Which needs to behave exactly as: identity(&temp()).method();)
+            //
+            // Iterate up to the enclosing destruction scope to find the same scope that will also
+            // be used for the result of the block itself.
+            while let Some(s) = visitor.cx.var_parent {
+                let parent = visitor.scope_tree.parent_map.get(&s).cloned();
+                if let Some(Scope { data: ScopeData::Destruction, .. }) = parent {
+                    break;
+                }
+                visitor.cx.var_parent = parent;
+            }
+        }
+    }
+
     if let Some(expr) = init {
-        record_rvalue_scope_if_borrow_expr(visitor, expr, blk_scope);
+        record_rvalue_scope_if_borrow_expr(visitor, expr, visitor.cx.var_parent);
 
         if let Some(pat) = pat {
             if is_binding_pat(pat) {
                 visitor.scope_tree.record_rvalue_candidate(
                     expr.hir_id,
-                    RvalueCandidate { target: expr.hir_id.local_id, lifetime: blk_scope },
+                    RvalueCandidate {
+                        target: expr.hir_id.local_id,
+                        lifetime: visitor.cx.var_parent,
+                    },
                 );
             }
         }
@@ -565,6 +617,7 @@ fn resolve_local<'tcx>(
     if let Some(expr) = init {
         visitor.visit_expr(expr);
     }
+
     if let Some(pat) = pat {
         visitor.visit_pat(pat);
     }
@@ -626,6 +679,7 @@ fn resolve_local<'tcx>(
 
             PatKind::Ref(_, _)
             | PatKind::Binding(hir::BindingMode(hir::ByRef::No, _), ..)
+            | PatKind::Missing
             | PatKind::Wild
             | PatKind::Never
             | PatKind::Expr(_)
@@ -642,6 +696,7 @@ fn resolve_local<'tcx>(
     ///        | [ ..., E&, ... ]
     ///        | ( ..., E&, ... )
     ///        | {...; E&}
+    ///        | { super let ... = E&; ... }
     ///        | if _ { ...; E& } else { ...; E& }
     ///        | match _ { ..., _ => E&, ... }
     ///        | box E&
@@ -678,6 +733,13 @@ fn resolve_local<'tcx>(
                 if let Some(subexpr) = block.expr {
                     record_rvalue_scope_if_borrow_expr(visitor, subexpr, blk_id);
                 }
+                for stmt in block.stmts {
+                    if let hir::StmtKind::Let(local) = stmt.kind
+                        && let Some(_) = local.super_
+                    {
+                        visitor.extended_super_lets.insert(local.pat.hir_id.local_id, blk_id);
+                    }
+                }
             }
             hir::ExprKind::If(_, then_block, else_block) => {
                 record_rvalue_scope_if_borrow_expr(visitor, then_block, blk_id);
@@ -803,7 +865,7 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
                     local_id: body.value.hir_id.local_id,
                     data: ScopeData::Destruction,
                 });
-                resolve_local(this, None, Some(body.value));
+                resolve_local(this, None, Some(body.value), LetKind::Regular);
             }
         })
     }
@@ -821,7 +883,11 @@ impl<'tcx> Visitor<'tcx> for ScopeResolutionVisitor<'tcx> {
         resolve_expr(self, ex, false);
     }
     fn visit_local(&mut self, l: &'tcx LetStmt<'tcx>) {
-        resolve_local(self, Some(l.pat), l.init)
+        let let_kind = match l.super_ {
+            Some(_) => LetKind::Super,
+            None => LetKind::Regular,
+        };
+        resolve_local(self, Some(l.pat), l.init, let_kind);
     }
     fn visit_inline_const(&mut self, c: &'tcx hir::ConstBlock) {
         let body = self.tcx.hir_body(c.body);
@@ -850,6 +916,7 @@ pub(crate) fn region_scope_tree(tcx: TyCtxt<'_>, def_id: DefId) -> &ScopeTree {
             cx: Context { parent: None, var_parent: None },
             pessimistic_yield: false,
             fixup_scopes: vec![],
+            extended_super_lets: Default::default(),
         };
 
         visitor.scope_tree.root_body = Some(body.value.hir_id);
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 83d095ab72e..6292d03bf6a 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -631,7 +631,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
         // Ignore `'static` lifetimes for the purpose of this lint: it's
         // because we know it outlives everything and so doesn't give meaningful
         // clues. Also ignore `ReError`, to avoid knock-down errors.
-        if let ty::ReStatic | ty::ReError(_) = **region_a {
+        if let ty::ReStatic | ty::ReError(_) = region_a.kind() {
             continue;
         }
         // For each region argument (e.g., `'a` in our example), check for a
@@ -672,7 +672,7 @@ fn gather_gat_bounds<'tcx, T: TypeFoldable<TyCtxt<'tcx>>>(
             // Again, skip `'static` because it outlives everything. Also, we trivially
             // know that a region outlives itself. Also ignore `ReError`, to avoid
             // knock-down errors.
-            if matches!(**region_b, ty::ReStatic | ty::ReError(_)) || region_a == region_b {
+            if matches!(region_b.kind(), ty::ReStatic | ty::ReError(_)) || region_a == region_b {
                 continue;
             }
             if region_known_to_outlive(tcx, item_def_id, param_env, wf_tys, *region_a, *region_b) {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 1f3f0b754bb..8ad9d80c6b5 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -656,7 +656,7 @@ fn infringing_fields_error<'tcx>(
                                 .entry((ty.clone(), predicate.clone()))
                                 .or_default()
                                 .push(origin.span());
-                            if let ty::RegionKind::ReEarlyParam(ebr) = *b
+                            if let ty::RegionKind::ReEarlyParam(ebr) = b.kind()
                                 && ebr.has_name()
                             {
                                 bounds.push((b.to_string(), a.to_string(), None));
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index 625f51dd29e..69b921fccbf 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -14,6 +14,7 @@
 //! At present, however, we do run collection across all items in the
 //! crate as a kind of pass. This should eventually be factored away.
 
+use std::assert_matches::assert_matches;
 use std::cell::Cell;
 use std::iter;
 use std::ops::Bound;
@@ -42,7 +43,6 @@ use rustc_trait_selection::infer::InferCtxtExt;
 use rustc_trait_selection::traits::ObligationCtxt;
 use tracing::{debug, instrument};
 
-use crate::check::intrinsic::intrinsic_operation_unsafety;
 use crate::errors;
 use crate::hir_ty_lowering::errors::assoc_kind_str;
 use crate::hir_ty_lowering::{FeedConstTy, HirTyLowerer, RegionInferReason};
@@ -1345,7 +1345,8 @@ fn fn_sig(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<'_, ty::PolyFn
             compute_sig_of_foreign_fn_decl(tcx, def_id, sig.decl, abi, sig.header.safety())
         }
 
-        Ctor(data) | Variant(hir::Variant { data, .. }) if data.ctor().is_some() => {
+        Ctor(data) => {
+            assert_matches!(data.ctor(), Some(_));
             let adt_def_id = tcx.hir_get_parent_item(hir_id).def_id.to_def_id();
             let ty = tcx.type_of(adt_def_id).instantiate_identity();
             let inputs = data.fields().iter().map(|f| tcx.type_of(f.def_id).instantiate_identity());
@@ -1417,7 +1418,7 @@ fn recover_infer_ret_ty<'tcx>(
         GenericParamKind::Lifetime { .. } => true,
         _ => false,
     });
-    let fn_sig = fold_regions(tcx, fn_sig, |r, _| match *r {
+    let fn_sig = fold_regions(tcx, fn_sig, |r, _| match r.kind() {
         ty::ReErased => {
             if has_region_params {
                 ty::Region::new_error_with_message(
@@ -1704,18 +1705,13 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
     abi: ExternAbi,
     safety: hir::Safety,
 ) -> ty::PolyFnSig<'tcx> {
-    let safety = if abi == ExternAbi::RustIntrinsic {
-        intrinsic_operation_unsafety(tcx, def_id)
-    } else {
-        safety
-    };
     let hir_id = tcx.local_def_id_to_hir_id(def_id);
     let fty =
         ItemCtxt::new(tcx, def_id).lowerer().lower_fn_ty(hir_id, safety, abi, decl, None, None);
 
     // Feature gate SIMD types in FFI, since I am not sure that the
     // ABIs are handled at all correctly. -huonw
-    if abi != ExternAbi::RustIntrinsic && !tcx.features().simd_ffi() {
+    if !tcx.features().simd_ffi() {
         let check = |hir_ty: &hir::Ty<'_>, ty: Ty<'_>| {
             if ty.is_simd() {
                 let snip = tcx
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 776b23bea8e..e90a1cc24c1 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -172,33 +172,9 @@ fn gather_explicit_predicates_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::Gen
     };
 
     if let Node::TraitItem(item) = node {
-        let parent = tcx.local_parent(item.hir_id().owner.def_id);
-        let Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
-            unreachable!();
-        };
-
-        let (trait_generics, trait_bounds) = match parent_trait.kind {
-            hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
-            hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
-            _ => unreachable!(),
-        };
-
-        // Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
-        // they are not added as super trait bounds to the trait itself. See comment on
-        // `requires_default_supertraits` for more details.
-        if !icx.lowerer().requires_default_supertraits(trait_bounds, trait_generics) {
-            let mut bounds = Vec::new();
-            let self_ty_where_predicates = (parent, item.generics.predicates);
-            icx.lowerer().add_default_traits_with_filter(
-                &mut bounds,
-                tcx.types.self_param,
-                &[],
-                Some(self_ty_where_predicates),
-                item.span,
-                |tr| tr != hir::LangItem::Sized,
-            );
-            predicates.extend(bounds);
-        }
+        let mut bounds = Vec::new();
+        icx.lowerer().add_default_trait_item_bounds(item, &mut bounds);
+        predicates.extend(bounds);
     }
 
     let generics = tcx.generics_of(def_id);
@@ -383,7 +359,7 @@ fn compute_bidirectional_outlives_predicates<'tcx>(
 ) {
     for param in opaque_own_params {
         let orig_lifetime = tcx.map_opaque_lifetime_to_parent_lifetime(param.def_id.expect_local());
-        if let ty::ReEarlyParam(..) = *orig_lifetime {
+        if let ty::ReEarlyParam(..) = orig_lifetime.kind() {
             let dup_lifetime = ty::Region::new_early_param(
                 tcx,
                 ty::EarlyParamRegion { index: param.index, name: param.name },
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
index 3fe3d71b32d..772197a53ac 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of/opaque.rs
@@ -183,25 +183,23 @@ impl<'tcx> TaitConstraintLocator<'tcx> {
                     self.non_defining_use_in_defining_scope(item_def_id);
                 }
             }
-            DefiningScopeKind::MirBorrowck => {
-                let borrowck_result = tcx.mir_borrowck(item_def_id);
-                if let Some(guar) = borrowck_result.tainted_by_errors {
-                    self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
-                } else if let Some(&hidden_type) =
-                    borrowck_result.concrete_opaque_types.get(&self.def_id)
-                {
-                    debug!(?hidden_type, "found constraint");
-                    self.insert_found(hidden_type);
-                } else if let Err(guar) = tcx
-                    .type_of_opaque_hir_typeck(self.def_id)
-                    .instantiate_identity()
-                    .error_reported()
-                {
-                    self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
-                } else {
-                    self.non_defining_use_in_defining_scope(item_def_id);
+            DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(item_def_id) {
+                Err(guar) => self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar)),
+                Ok(concrete_opaque_types) => {
+                    if let Some(&hidden_type) = concrete_opaque_types.0.get(&self.def_id) {
+                        debug!(?hidden_type, "found constraint");
+                        self.insert_found(hidden_type);
+                    } else if let Err(guar) = tcx
+                        .type_of_opaque_hir_typeck(self.def_id)
+                        .instantiate_identity()
+                        .error_reported()
+                    {
+                        self.insert_found(ty::OpaqueHiddenType::new_error(tcx, guar));
+                    } else {
+                        self.non_defining_use_in_defining_scope(item_def_id);
+                    }
                 }
-            }
+            },
         }
     }
 }
@@ -264,20 +262,20 @@ pub(super) fn find_opaque_ty_constraints_for_rpit<'tcx>(
                 Ty::new_diverging_default(tcx)
             }
         }
-        DefiningScopeKind::MirBorrowck => {
-            let borrowck_result = tcx.mir_borrowck(owner_def_id);
-            if let Some(guar) = borrowck_result.tainted_by_errors {
-                Ty::new_error(tcx, guar)
-            } else if let Some(hidden_ty) = borrowck_result.concrete_opaque_types.get(&def_id) {
-                hidden_ty.ty
-            } else {
-                let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
-                if let Err(guar) = hir_ty.error_reported() {
-                    Ty::new_error(tcx, guar)
+        DefiningScopeKind::MirBorrowck => match tcx.mir_borrowck(owner_def_id) {
+            Ok(concrete_opaque_types) => {
+                if let Some(hidden_ty) = concrete_opaque_types.0.get(&def_id) {
+                    hidden_ty.ty
                 } else {
-                    hir_ty
+                    let hir_ty = tcx.type_of_opaque_hir_typeck(def_id).instantiate_identity();
+                    if let Err(guar) = hir_ty.error_reported() {
+                        Ty::new_error(tcx, guar)
+                    } else {
+                        hir_ty
+                    }
                 }
             }
-        }
+            Err(guar) => Ty::new_error(tcx, guar),
+        },
     }
 }
diff --git a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
index 53866aa27b1..951eda72ffe 100644
--- a/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
+++ b/compiler/rustc_hir_analysis/src/constrained_generic_params.rs
@@ -80,7 +80,7 @@ impl<'tcx> TypeVisitor<TyCtxt<'tcx>> for ParameterCollector {
     }
 
     fn visit_region(&mut self, r: ty::Region<'tcx>) {
-        if let ty::ReEarlyParam(data) = *r {
+        if let ty::ReEarlyParam(data) = r.kind() {
             self.parameters.push(Parameter::from(data));
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/errors.rs b/compiler/rustc_hir_analysis/src/errors.rs
index f2560f22874..e6090a128b1 100644
--- a/compiler/rustc_hir_analysis/src/errors.rs
+++ b/compiler/rustc_hir_analysis/src/errors.rs
@@ -1707,3 +1707,11 @@ pub(crate) enum SupertraitItemShadowee {
         traits: DiagSymbolList,
     },
 }
+
+#[derive(Diagnostic)]
+#[diag(hir_analysis_self_in_type_alias, code = E0411)]
+pub(crate) struct SelfInTypeAlias {
+    #[primary_span]
+    #[label]
+    pub span: Span,
+}
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
index c3bb860538e..55087d1f400 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs
@@ -43,12 +43,12 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     }
 
     /// Checks whether `Self: DefaultAutoTrait` bounds should be added on trait super bounds
-    /// or associative items.
+    /// or associated items.
     ///
     /// To keep backward compatibility with existing code, `experimental_default_bounds` bounds
     /// should be added everywhere, including super bounds. However this causes a huge performance
     /// costs. For optimization purposes instead of adding default supertraits, bounds
-    /// are added to the associative items:
+    /// are added to the associated items:
     ///
     /// ```ignore(illustrative)
     /// // Default bounds are generated in the following way:
@@ -81,7 +81,7 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
     ///
     /// Therefore, `experimental_default_bounds` are still being added to supertraits if
     /// the `SelfTyParam` or `AssocItemConstraint` were found in a trait header.
-    pub(crate) fn requires_default_supertraits(
+    fn requires_default_supertraits(
         &self,
         hir_bounds: &'tcx [hir::GenericBound<'tcx>],
         hir_generics: &'tcx hir::Generics<'tcx>,
@@ -120,6 +120,43 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         found
     }
 
+    /// Implicitly add `Self: DefaultAutoTrait` clauses on trait associated items if
+    /// they are not added as super trait bounds to the trait itself. See
+    /// `requires_default_supertraits` for more information.
+    pub(crate) fn add_default_trait_item_bounds(
+        &self,
+        trait_item: &hir::TraitItem<'tcx>,
+        bounds: &mut Vec<(ty::Clause<'tcx>, Span)>,
+    ) {
+        let tcx = self.tcx();
+        if !tcx.sess.opts.unstable_opts.experimental_default_bounds {
+            return;
+        }
+
+        let parent = tcx.local_parent(trait_item.hir_id().owner.def_id);
+        let hir::Node::Item(parent_trait) = tcx.hir_node_by_def_id(parent) else {
+            unreachable!();
+        };
+
+        let (trait_generics, trait_bounds) = match parent_trait.kind {
+            hir::ItemKind::Trait(_, _, _, generics, supertraits, _) => (generics, supertraits),
+            hir::ItemKind::TraitAlias(_, generics, supertraits) => (generics, supertraits),
+            _ => unreachable!(),
+        };
+
+        if !self.requires_default_supertraits(trait_bounds, trait_generics) {
+            let self_ty_where_predicates = (parent, trait_item.generics.predicates);
+            self.add_default_traits_with_filter(
+                bounds,
+                tcx.types.self_param,
+                &[],
+                Some(self_ty_where_predicates),
+                trait_item.span,
+                |tr| tr != hir::LangItem::Sized,
+            );
+        }
+    }
+
     /// Lazily sets `experimental_default_bounds` to true on trait super bounds.
     /// See `requires_default_supertraits` for more information.
     pub(crate) fn add_default_super_traits(
@@ -130,6 +167,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         hir_generics: &'tcx hir::Generics<'tcx>,
         span: Span,
     ) {
+        if !self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
+            return;
+        }
+
         assert!(matches!(self.tcx().def_kind(trait_def_id), DefKind::Trait | DefKind::TraitAlias));
         if self.requires_default_supertraits(hir_bounds, hir_generics) {
             let self_ty_where_predicates = (trait_def_id, hir_generics.predicates);
@@ -263,11 +304,10 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
                 seen_unbound = true;
             }
             let emit_relax_err = || {
-                let unbound_traits =
-                    match self.tcx().sess.opts.unstable_opts.experimental_default_bounds {
-                        true => "`?Sized` and `experimental_default_bounds`",
-                        false => "`?Sized`",
-                    };
+                let unbound_traits = match tcx.sess.opts.unstable_opts.experimental_default_bounds {
+                    true => "`?Sized` and `experimental_default_bounds`",
+                    false => "`?Sized`",
+                };
                 // There was a `?Trait` bound, but it was neither `?Sized` nor `experimental_default_bounds`.
                 tcx.dcx().span_err(
                     unbound.span,
diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
index aeebe45f881..e64cd8ec302 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/dyn_compatibility.rs
@@ -16,6 +16,7 @@ use smallvec::{SmallVec, smallvec};
 use tracing::{debug, instrument};
 
 use super::HirTyLowerer;
+use crate::errors::SelfInTypeAlias;
 use crate::hir_ty_lowering::{
     GenericArgCountMismatch, GenericArgCountResult, PredicateFilter, RegionInferReason,
 };
@@ -125,6 +126,19 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
         // ```
         let mut projection_bounds = FxIndexMap::default();
         for (proj, proj_span) in elaborated_projection_bounds {
+            let proj = proj.map_bound(|mut b| {
+                if let Some(term_ty) = &b.term.as_type() {
+                    let references_self = term_ty.walk().any(|arg| arg == dummy_self.into());
+                    if references_self {
+                        // With trait alias and type alias combined, type resolver
+                        // may not be able to catch all illegal `Self` usages (issue 139082)
+                        let guar = tcx.dcx().emit_err(SelfInTypeAlias { span });
+                        b.term = replace_dummy_self_with_error(tcx, b.term, guar);
+                    }
+                }
+                b
+            });
+
             let key = (
                 proj.skip_binder().projection_term.def_id,
                 tcx.anonymize_bound_vars(
diff --git a/compiler/rustc_hir_analysis/src/hir_wf_check.rs b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
index c01b81563dc..64c1a78bd1c 100644
--- a/compiler/rustc_hir_analysis/src/hir_wf_check.rs
+++ b/compiler/rustc_hir_analysis/src/hir_wf_check.rs
@@ -4,7 +4,7 @@ use rustc_infer::infer::TyCtxtInferExt;
 use rustc_infer::traits::{ObligationCause, WellFormedLoc};
 use rustc_middle::bug;
 use rustc_middle::query::Providers;
-use rustc_middle::ty::{self, TyCtxt, TypingMode, fold_regions};
+use rustc_middle::ty::{self, TyCtxt, TypeVisitableExt, TypingMode, fold_regions};
 use rustc_span::def_id::LocalDefId;
 use rustc_trait_selection::traits::{self, ObligationCtxt};
 use tracing::debug;
@@ -77,6 +77,15 @@ fn diagnostic_hir_wf_check<'tcx>(
             let tcx_ty = fold_regions(self.tcx, tcx_ty, |r, _| {
                 if r.is_bound() { self.tcx.lifetimes.re_erased } else { r }
             });
+
+            // We may be checking the WFness of a type in an opaque with a non-lifetime bound.
+            // Perhaps we could rebind all the escaping bound vars, but they're coming from
+            // arbitrary debruijn indices and aren't particularly important anyways, since they
+            // are only coming from `feature(non_lifetime_binders)` anyways.
+            if tcx_ty.has_escaping_bound_vars() {
+                return;
+            }
+
             let cause = traits::ObligationCause::new(
                 ty.span,
                 self.def_id,
diff --git a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
index a0faa5e8429..780c27d4595 100644
--- a/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/implicit_infer.rs
@@ -24,8 +24,8 @@ pub(super) fn infer_predicates(
 
     // If new predicates were added then we need to re-calculate
     // all crates since there could be new implied predicates.
-    loop {
-        let mut predicates_added = false;
+    for i in 0.. {
+        let mut predicates_added = vec![];
 
         // Visit all the crates and infer predicates
         for id in tcx.hir_free_items() {
@@ -83,14 +83,27 @@ pub(super) fn infer_predicates(
                 .get(&item_did.to_def_id())
                 .map_or(0, |p| p.as_ref().skip_binder().len());
             if item_required_predicates.len() > item_predicates_len {
-                predicates_added = true;
+                predicates_added.push(item_did);
                 global_inferred_outlives
                     .insert(item_did.to_def_id(), ty::EarlyBinder::bind(item_required_predicates));
             }
         }
 
-        if !predicates_added {
+        if predicates_added.is_empty() {
+            // We've reached a fixed point.
             break;
+        } else if !tcx.recursion_limit().value_within_limit(i) {
+            let msg = if let &[id] = &predicates_added[..] {
+                format!("overflow computing implied lifetime bounds for `{}`", tcx.def_path_str(id),)
+            } else {
+                "overflow computing implied lifetime bounds".to_string()
+            };
+            tcx.dcx()
+                .struct_span_fatal(
+                    predicates_added.iter().map(|id| tcx.def_span(*id)).collect::<Vec<_>>(),
+                    msg,
+                )
+                .emit();
         }
     }
 
diff --git a/compiler/rustc_hir_analysis/src/outlives/utils.rs b/compiler/rustc_hir_analysis/src/outlives/utils.rs
index d0a2a2230ab..044fb64ca82 100644
--- a/compiler/rustc_hir_analysis/src/outlives/utils.rs
+++ b/compiler/rustc_hir_analysis/src/outlives/utils.rs
@@ -146,7 +146,7 @@ pub(crate) fn insert_outlives_predicate<'tcx>(
 
 fn is_free_region(region: Region<'_>) -> bool {
     // First, screen for regions that might appear in a type header.
-    match *region {
+    match region.kind() {
         // These correspond to `T: 'a` relationships:
         //
         //     struct Foo<'a, T> {
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 8475903c68f..23223de918c 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -428,7 +428,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
         region: ty::Region<'tcx>,
         variance: VarianceTermPtr<'a>,
     ) {
-        match *region {
+        match region.kind() {
             ty::ReEarlyParam(ref data) => {
                 self.add_constraint(current, data.index, variance);
             }
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 0800d99e945..dbba45dc7bb 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -44,13 +44,13 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
         return &[];
     }
 
-    match tcx.def_kind(item_def_id) {
+    let kind = tcx.def_kind(item_def_id);
+    match kind {
         DefKind::Fn
         | DefKind::AssocFn
         | DefKind::Enum
         | DefKind::Struct
         | DefKind::Union
-        | DefKind::Variant
         | DefKind::Ctor(..) => {
             // These are inferred.
             let crate_map = tcx.crate_variances(());
@@ -89,7 +89,11 @@ fn variances_of(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Variance] {
     }
 
     // Variance not relevant.
-    span_bug!(tcx.def_span(item_def_id), "asked to compute variance for wrong kind of item");
+    span_bug!(
+        tcx.def_span(item_def_id),
+        "asked to compute variance for {}",
+        kind.descr(item_def_id.to_def_id())
+    );
 }
 
 #[derive(Debug, Copy, Clone)]