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/astconv/mod.rs13
-rw-r--r--compiler/rustc_hir_analysis/src/check/check.rs6
-rw-r--r--compiler/rustc_hir_analysis/src/check/compare_impl_item.rs8
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsic.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/intrinsicck.rs38
-rw-r--r--compiler/rustc_hir_analysis/src/check/mod.rs41
-rw-r--r--compiler/rustc_hir_analysis/src/check/region.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/check/wfcheck.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/builtin.rs9
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/coherence/mod.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect.rs37
-rw-r--r--compiler/rustc_hir_analysis/src/collect/predicates_of.rs5
-rw-r--r--compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/collect/type_of.rs255
-rw-r--r--compiler/rustc_hir_analysis/src/lib.rs4
-rw-r--r--compiler/rustc_hir_analysis/src/variance/constraints.rs2
-rw-r--r--compiler/rustc_hir_analysis/src/variance/mod.rs2
18 files changed, 199 insertions, 235 deletions
diff --git a/compiler/rustc_hir_analysis/src/astconv/mod.rs b/compiler/rustc_hir_analysis/src/astconv/mod.rs
index 8d1156c1771..992316edb63 100644
--- a/compiler/rustc_hir_analysis/src/astconv/mod.rs
+++ b/compiler/rustc_hir_analysis/src/astconv/mod.rs
@@ -447,14 +447,9 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                         handle_ty_args(has_default, &inf.to_ty())
                     }
                     (GenericParamDefKind::Const { .. }, GenericArg::Const(ct)) => {
-                        ty::Const::from_opt_const_arg_anon_const(
-                            tcx,
-                            ty::WithOptConstParam {
-                                did: ct.value.def_id,
-                                const_param_did: Some(param.def_id),
-                            },
-                        )
-                        .into()
+                        let did = ct.value.def_id;
+                        tcx.feed_anon_const_type(did, tcx.type_of(param.def_id));
+                        ty::Const::from_anon_const(tcx, did).into()
                     }
                     (&GenericParamDefKind::Const { .. }, hir::GenericArg::Infer(inf)) => {
                         let ty = tcx
@@ -2061,7 +2056,7 @@ impl<'o, 'tcx> dyn AstConv<'tcx> + 'o {
                             err.note("enum variants can't have type parameters");
                             let type_name = tcx.item_name(adt_def.did());
                             let msg = format!(
-                                "you might have meant to specity type parameters on enum \
+                                "you might have meant to specify type parameters on enum \
                                  `{type_name}`"
                             );
                             let Some(args) = assoc_segment.args else { return; };
diff --git a/compiler/rustc_hir_analysis/src/check/check.rs b/compiler/rustc_hir_analysis/src/check/check.rs
index 0bb98fdf2a2..ad2624a5d2d 100644
--- a/compiler/rustc_hir_analysis/src/check/check.rs
+++ b/compiler/rustc_hir_analysis/src/check/check.rs
@@ -15,7 +15,7 @@ use rustc_infer::infer::opaque_types::ConstrainOpaqueTypeRegionVisitor;
 use rustc_infer::infer::outlives::env::OutlivesEnvironment;
 use rustc_infer::infer::{DefiningAnchor, RegionVariableOrigin, TyCtxtInferExt};
 use rustc_infer::traits::{Obligation, TraitEngineExt as _};
-use rustc_lint::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
+use rustc_lint_defs::builtin::REPR_TRANSPARENT_EXTERNAL_PRIVATE_FIELDS;
 use rustc_middle::hir::nested_filter;
 use rustc_middle::middle::stability::EvalResult;
 use rustc_middle::ty::layout::{LayoutError, MAX_SIMD_LANES};
@@ -494,7 +494,7 @@ fn check_item_type(tcx: TyCtxt<'_>, id: hir::ItemId) {
     debug!(
         "check_item_type(it.def_id={:?}, it.name={})",
         id.owner_id,
-        tcx.def_path_str(id.owner_id.to_def_id())
+        tcx.def_path_str(id.owner_id)
     );
     let _indenter = indenter();
     match tcx.def_kind(id.owner_id) {
@@ -863,7 +863,7 @@ fn check_impl_items_against_trait<'tcx>(
         if !missing_items.is_empty() {
             let full_impl_span =
                 tcx.hir().span_with_body(tcx.hir().local_def_id_to_hir_id(impl_id));
-            missing_items_err(tcx, tcx.def_span(impl_id), &missing_items, full_impl_span);
+            missing_items_err(tcx, impl_id, &missing_items, full_impl_span);
         }
 
         if let Some(missing_items) = must_implement_one_of {
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 5d119a7737a..fe87aae8ed1 100644
--- a/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
+++ b/compiler/rustc_hir_analysis/src/check/compare_impl_item.rs
@@ -579,7 +579,7 @@ fn compare_asyncness<'tcx>(
 pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
     tcx: TyCtxt<'tcx>,
     impl_m_def_id: LocalDefId,
-) -> Result<&'tcx FxHashMap<DefId, Ty<'tcx>>, ErrorGuaranteed> {
+) -> Result<&'tcx FxHashMap<DefId, ty::EarlyBinder<Ty<'tcx>>>, ErrorGuaranteed> {
     let impl_m = tcx.opt_associated_item(impl_m_def_id.to_def_id()).unwrap();
     let trait_m = tcx.opt_associated_item(impl_m.trait_item_def_id.unwrap()).unwrap();
     let impl_trait_ref =
@@ -782,14 +782,14 @@ pub(super) fn collect_return_position_impl_trait_in_trait_tys<'tcx>(
                     })
                 });
                 debug!(%ty);
-                collected_tys.insert(def_id, ty);
+                collected_tys.insert(def_id, ty::EarlyBinder(ty));
             }
             Err(err) => {
                 let reported = tcx.sess.delay_span_bug(
                     return_span,
                     format!("could not fully resolve: {ty} => {err:?}"),
                 );
-                collected_tys.insert(def_id, tcx.ty_error(reported));
+                collected_tys.insert(def_id, ty::EarlyBinder(tcx.ty_error(reported)));
             }
         }
     }
@@ -1317,7 +1317,7 @@ fn compare_number_of_generics<'tcx>(
                         impl_count,
                         kind,
                         pluralize!(impl_count),
-                        suffix.unwrap_or_else(String::new),
+                        suffix.unwrap_or_default(),
                     ),
                 );
             }
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index 854974d1605..0fcbaa2efab 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -198,7 +198,7 @@ pub fn check_intrinsic_type(tcx: TyCtxt<'_>, it: &hir::ForeignItem<'_>) {
             | sym::assert_zero_valid
             | sym::assert_mem_uninitialized_valid => (1, Vec::new(), tcx.mk_unit()),
             sym::forget => (1, vec![param(0)], tcx.mk_unit()),
-            sym::transmute => (2, vec![param(0)], param(1)),
+            sym::transmute | sym::transmute_unchecked => (2, vec![param(0)], param(1)),
             sym::prefetch_read_data
             | sym::prefetch_write_data
             | sym::prefetch_read_instruction
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
index 0d482b53afe..a28814681db 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsicck.rs
@@ -84,33 +84,45 @@ impl<'a, 'tcx> InlineAsmCtxt<'a, 'tcx> {
             ty::Adt(adt, substs) if adt.repr().simd() => {
                 let fields = &adt.non_enum_variant().fields;
                 let elem_ty = fields[FieldIdx::from_u32(0)].ty(self.tcx, substs);
-                match elem_ty.kind() {
-                    ty::Never | ty::Error(_) => return None,
-                    ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => {
-                        Some(InlineAsmType::VecI8(fields.len() as u64))
+
+                let (size, ty) = match elem_ty.kind() {
+                    ty::Array(ty, len) => {
+                        if let Some(len) =
+                            len.try_eval_target_usize(self.tcx, self.tcx.param_env(adt.did()))
+                        {
+                            (len, *ty)
+                        } else {
+                            return None;
+                        }
                     }
+                    _ => (fields.len() as u64, elem_ty),
+                };
+
+                match ty.kind() {
+                    ty::Never | ty::Error(_) => return None,
+                    ty::Int(IntTy::I8) | ty::Uint(UintTy::U8) => Some(InlineAsmType::VecI8(size)),
                     ty::Int(IntTy::I16) | ty::Uint(UintTy::U16) => {
-                        Some(InlineAsmType::VecI16(fields.len() as u64))
+                        Some(InlineAsmType::VecI16(size))
                     }
                     ty::Int(IntTy::I32) | ty::Uint(UintTy::U32) => {
-                        Some(InlineAsmType::VecI32(fields.len() as u64))
+                        Some(InlineAsmType::VecI32(size))
                     }
                     ty::Int(IntTy::I64) | ty::Uint(UintTy::U64) => {
-                        Some(InlineAsmType::VecI64(fields.len() as u64))
+                        Some(InlineAsmType::VecI64(size))
                     }
                     ty::Int(IntTy::I128) | ty::Uint(UintTy::U128) => {
-                        Some(InlineAsmType::VecI128(fields.len() as u64))
+                        Some(InlineAsmType::VecI128(size))
                     }
                     ty::Int(IntTy::Isize) | ty::Uint(UintTy::Usize) => {
                         Some(match self.tcx.sess.target.pointer_width {
-                            16 => InlineAsmType::VecI16(fields.len() as u64),
-                            32 => InlineAsmType::VecI32(fields.len() as u64),
-                            64 => InlineAsmType::VecI64(fields.len() as u64),
+                            16 => InlineAsmType::VecI16(size),
+                            32 => InlineAsmType::VecI32(size),
+                            64 => InlineAsmType::VecI64(size),
                             _ => unreachable!(),
                         })
                     }
-                    ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(fields.len() as u64)),
-                    ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(fields.len() as u64)),
+                    ty::Float(FloatTy::F32) => Some(InlineAsmType::VecF32(size)),
+                    ty::Float(FloatTy::F64) => Some(InlineAsmType::VecF64(size)),
                     _ => None,
                 }
             }
diff --git a/compiler/rustc_hir_analysis/src/check/mod.rs b/compiler/rustc_hir_analysis/src/check/mod.rs
index 8fe4c44fca4..4b3f3cf169d 100644
--- a/compiler/rustc_hir_analysis/src/check/mod.rs
+++ b/compiler/rustc_hir_analysis/src/check/mod.rs
@@ -198,7 +198,7 @@ fn report_forbidden_specialization(tcx: TyCtxt<'_>, impl_item: DefId, parent_imp
 
 fn missing_items_err(
     tcx: TyCtxt<'_>,
-    impl_span: Span,
+    impl_def_id: LocalDefId,
     missing_items: &[ty::AssocItem],
     full_impl_span: Span,
 ) {
@@ -211,6 +211,7 @@ fn missing_items_err(
         .collect::<Vec<_>>()
         .join("`, `");
 
+    let impl_span = tcx.def_span(impl_def_id);
     let mut err = struct_span_err!(
         tcx.sess,
         impl_span,
@@ -229,7 +230,11 @@ fn missing_items_err(
         tcx.sess.source_map().indentation_before(sugg_sp).unwrap_or_else(|| String::new());
 
     for &trait_item in missing_items {
-        let snippet = suggestion_signature(trait_item, tcx);
+        let snippet = suggestion_signature(
+            tcx,
+            trait_item,
+            tcx.impl_trait_ref(impl_def_id).unwrap().subst_identity(),
+        );
         let code = format!("{}{}\n{}", padding, snippet, padding);
         let msg = format!("implement the missing item: `{snippet}`");
         let appl = Applicability::HasPlaceholders;
@@ -301,11 +306,11 @@ fn default_body_is_unstable(
 /// Re-sugar `ty::GenericPredicates` in a way suitable to be used in structured suggestions.
 fn bounds_from_generic_predicates<'tcx>(
     tcx: TyCtxt<'tcx>,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
 ) -> (String, String) {
     let mut types: FxHashMap<Ty<'tcx>, Vec<DefId>> = FxHashMap::default();
     let mut projections = vec![];
-    for (predicate, _) in predicates.predicates {
+    for (predicate, _) in predicates {
         debug!("predicate {:?}", predicate);
         let bound_predicate = predicate.kind();
         match bound_predicate.skip_binder() {
@@ -367,7 +372,7 @@ fn fn_sig_suggestion<'tcx>(
     tcx: TyCtxt<'tcx>,
     sig: ty::FnSig<'tcx>,
     ident: Ident,
-    predicates: ty::GenericPredicates<'tcx>,
+    predicates: impl IntoIterator<Item = (ty::Predicate<'tcx>, Span)>,
     assoc: ty::AssocItem,
 ) -> String {
     let args = sig
@@ -436,7 +441,17 @@ pub fn ty_kind_suggestion(ty: Ty<'_>) -> Option<&'static str> {
 /// Return placeholder code for the given associated item.
 /// Similar to `ty::AssocItem::suggestion`, but appropriate for use as the code snippet of a
 /// structured suggestion.
-fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
+fn suggestion_signature<'tcx>(
+    tcx: TyCtxt<'tcx>,
+    assoc: ty::AssocItem,
+    impl_trait_ref: ty::TraitRef<'tcx>,
+) -> String {
+    let substs = ty::InternalSubsts::identity_for_item(tcx, assoc.def_id).rebase_onto(
+        tcx,
+        assoc.container_id(tcx),
+        impl_trait_ref.with_self_ty(tcx, tcx.types.self_param).substs,
+    );
+
     match assoc.kind {
         ty::AssocKind::Fn => {
             // We skip the binder here because the binder would deanonymize all
@@ -445,16 +460,22 @@ fn suggestion_signature(assoc: ty::AssocItem, tcx: TyCtxt<'_>) -> String {
             // regions just fine, showing `fn(&MyType)`.
             fn_sig_suggestion(
                 tcx,
-                tcx.fn_sig(assoc.def_id).subst_identity().skip_binder(),
+                tcx.fn_sig(assoc.def_id).subst(tcx, substs).skip_binder(),
                 assoc.ident(tcx),
-                tcx.predicates_of(assoc.def_id),
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
                 assoc,
             )
         }
-        ty::AssocKind::Type => format!("type {} = Type;", assoc.name),
+        ty::AssocKind::Type => {
+            let (generics, where_clauses) = bounds_from_generic_predicates(
+                tcx,
+                tcx.predicates_of(assoc.def_id).instantiate_own(tcx, substs),
+            );
+            format!("type {}{generics} = /* Type */{where_clauses};", assoc.name)
+        }
         ty::AssocKind::Const => {
             let ty = tcx.type_of(assoc.def_id).subst_identity();
-            let val = ty_kind_suggestion(ty).unwrap_or("value");
+            let val = ty_kind_suggestion(ty).unwrap_or("todo!()");
             format!("const {}: {} = {};", assoc.name, ty, val)
         }
     }
diff --git a/compiler/rustc_hir_analysis/src/check/region.rs b/compiler/rustc_hir_analysis/src/check/region.rs
index b28bfb1d54b..421b3df2d53 100644
--- a/compiler/rustc_hir_analysis/src/check/region.rs
+++ b/compiler/rustc_hir_analysis/src/check/region.rs
@@ -12,7 +12,7 @@ use rustc_hir as hir;
 use rustc_hir::def_id::DefId;
 use rustc_hir::intravisit::{self, Visitor};
 use rustc_hir::{Arm, Block, Expr, Local, Pat, PatKind, Stmt};
-use rustc_index::vec::Idx;
+use rustc_index::Idx;
 use rustc_middle::middle::region::*;
 use rustc_middle::ty::TyCtxt;
 use rustc_span::source_map;
diff --git a/compiler/rustc_hir_analysis/src/check/wfcheck.rs b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
index 53197bc8491..b2ebbf993a1 100644
--- a/compiler/rustc_hir_analysis/src/check/wfcheck.rs
+++ b/compiler/rustc_hir_analysis/src/check/wfcheck.rs
@@ -155,7 +155,7 @@ fn check_item<'tcx>(tcx: TyCtxt<'tcx>, item: &'tcx hir::Item<'tcx>) {
 
     debug!(
         ?item.owner_id,
-        item.name = ? tcx.def_path_str(def_id.to_def_id())
+        item.name = ? tcx.def_path_str(def_id)
     );
 
     match item.kind {
@@ -251,7 +251,7 @@ fn check_foreign_item(tcx: TyCtxt<'_>, item: &hir::ForeignItem<'_>) {
 
     debug!(
         ?item.owner_id,
-        item.name = ? tcx.def_path_str(def_id.to_def_id())
+        item.name = ? tcx.def_path_str(def_id)
     );
 
     match item.kind {
diff --git a/compiler/rustc_hir_analysis/src/coherence/builtin.rs b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
index 0f40cca9427..611ce13b739 100644
--- a/compiler/rustc_hir_analysis/src/coherence/builtin.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/builtin.rs
@@ -74,16 +74,15 @@ fn visit_implementation_of_copy(tcx: TyCtxt<'_>, impl_did: LocalDefId) {
 
     debug!("visit_implementation_of_copy: self_type={:?} (free)", self_type);
 
-    let span = match tcx.hir().expect_item(impl_did).kind {
-        ItemKind::Impl(hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. }) => return,
-        ItemKind::Impl(impl_) => impl_.self_ty.span,
-        _ => bug!("expected Copy impl item"),
+    let span = match tcx.hir().expect_item(impl_did).expect_impl() {
+        hir::Impl { polarity: hir::ImplPolarity::Negative(_), .. } => return,
+        hir::Impl { self_ty, .. } => self_ty.span,
     };
 
     let cause = traits::ObligationCause::misc(span, impl_did);
     match type_allowed_to_implement_copy(tcx, param_env, self_type, cause) {
         Ok(()) => {}
-        Err(CopyImplementationError::InfrigingFields(fields)) => {
+        Err(CopyImplementationError::InfringingFields(fields)) => {
             let mut err = struct_span_err!(
                 tcx.sess,
                 span,
diff --git a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
index ad76e2bed20..bd6252344b2 100644
--- a/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/inherent_impls_overlap.rs
@@ -3,7 +3,7 @@ use rustc_errors::struct_span_err;
 use rustc_hir as hir;
 use rustc_hir::def::DefKind;
 use rustc_hir::def_id::DefId;
-use rustc_index::vec::IndexVec;
+use rustc_index::IndexVec;
 use rustc_middle::traits::specialization_graph::OverlapMode;
 use rustc_middle::ty::{self, TyCtxt};
 use rustc_span::Symbol;
diff --git a/compiler/rustc_hir_analysis/src/coherence/mod.rs b/compiler/rustc_hir_analysis/src/coherence/mod.rs
index 465e787c92a..ac393ee15a6 100644
--- a/compiler/rustc_hir_analysis/src/coherence/mod.rs
+++ b/compiler/rustc_hir_analysis/src/coherence/mod.rs
@@ -22,7 +22,7 @@ fn check_impl(tcx: TyCtxt<'_>, impl_def_id: LocalDefId, trait_ref: ty::TraitRef<
     debug!(
         "(checking implementation) adding impl for trait '{:?}', item '{}'",
         trait_ref,
-        tcx.def_path_str(impl_def_id.to_def_id())
+        tcx.def_path_str(impl_def_id)
     );
 
     // Skip impls where one of the self type is an error type.
diff --git a/compiler/rustc_hir_analysis/src/collect.rs b/compiler/rustc_hir_analysis/src/collect.rs
index cbbaf8f857d..9fe0c07814e 100644
--- a/compiler/rustc_hir_analysis/src/collect.rs
+++ b/compiler/rustc_hir_analysis/src/collect.rs
@@ -55,7 +55,6 @@ fn collect_mod_item_types(tcx: TyCtxt<'_>, module_def_id: LocalDefId) {
 pub fn provide(providers: &mut Providers) {
     resolve_bound_vars::provide(providers);
     *providers = Providers {
-        opt_const_param_of: type_of::opt_const_param_of,
         type_of: type_of::type_of,
         item_bounds: item_bounds::item_bounds,
         explicit_item_bounds: item_bounds::explicit_item_bounds,
@@ -1147,8 +1146,14 @@ fn infer_return_ty_for_fn_sig<'tcx>(
 
             let mut visitor = HirPlaceholderCollector::default();
             visitor.visit_ty(ty);
+
             let mut diag = bad_placeholder(tcx, visitor.0, "return type");
             let ret_ty = fn_sig.output();
+            // Don't leak types into signatures unless they're nameable!
+            // For example, if a function returns itself, we don't want that
+            // recursive function definition to leak out into the fn sig.
+            let mut should_recover = false;
+
             if let Some(ret_ty) = ret_ty.make_suggestable(tcx, false) {
                 diag.span_suggestion(
                     ty.span,
@@ -1156,15 +1161,7 @@ fn infer_return_ty_for_fn_sig<'tcx>(
                     ret_ty,
                     Applicability::MachineApplicable,
                 );
-            } else if matches!(ret_ty.kind(), ty::FnDef(..))
-                && let Some(fn_sig) = ret_ty.fn_sig(tcx).make_suggestable(tcx, false)
-            {
-                diag.span_suggestion(
-                    ty.span,
-                    "replace with the correct return type",
-                    fn_sig,
-                    Applicability::MachineApplicable,
-                );
+                should_recover = true;
             } else if let Some(sugg) = suggest_impl_trait(tcx, ret_ty, ty.span, def_id) {
                 diag.span_suggestion(
                     ty.span,
@@ -1182,9 +1179,20 @@ fn infer_return_ty_for_fn_sig<'tcx>(
                      https://doc.rust-lang.org/book/ch13-01-closures.html",
                 );
             }
-            diag.emit();
 
-            ty::Binder::dummy(fn_sig)
+            let guar = diag.emit();
+
+            if should_recover {
+                ty::Binder::dummy(fn_sig)
+            } else {
+                ty::Binder::dummy(tcx.mk_fn_sig(
+                    fn_sig.inputs().iter().copied(),
+                    tcx.ty_error(guar),
+                    fn_sig.c_variadic,
+                    fn_sig.unsafety,
+                    fn_sig.abi,
+                ))
+            }
         }
         None => icx.astconv().ty_of_fn(
             hir_id,
@@ -1457,10 +1465,7 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
 }
 
 fn is_foreign_item(tcx: TyCtxt<'_>, def_id: LocalDefId) -> bool {
-    match tcx.hir().get_by_def_id(def_id) {
-        Node::ForeignItem(..) => true,
-        _ => false,
-    }
+    matches!(tcx.hir().get_by_def_id(def_id), Node::ForeignItem(..))
 }
 
 fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::GeneratorKind> {
diff --git a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
index 9358ed61292..8c414521b76 100644
--- a/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/predicates_of.rs
@@ -645,9 +645,8 @@ pub(super) fn implied_predicates_with_filter(
     };
 
     // Combine the two lists to form the complete set of superbounds:
-    let implied_bounds = &*tcx
-        .arena
-        .alloc_from_iter(superbounds.predicates().into_iter().chain(where_bounds_that_match));
+    let implied_bounds =
+        &*tcx.arena.alloc_from_iter(superbounds.predicates().chain(where_bounds_that_match));
     debug!(?implied_bounds);
 
     // Now require that immediate supertraits are converted,
diff --git a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
index e758fe95d9c..3cb217335bd 100644
--- a/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
+++ b/compiler/rustc_hir_analysis/src/collect/resolve_bound_vars.rs
@@ -1333,7 +1333,7 @@ impl<'a, 'tcx> BoundVarContext<'a, 'tcx> {
 
         // We may fail to resolve higher-ranked lifetimes that are mentioned by APIT.
         // AST-based resolution does not care for impl-trait desugaring, which are the
-        // responibility of lowering. This may create a mismatch between the resolution
+        // responsibility of lowering. This may create a mismatch between the resolution
         // AST found (`region_def_id`) which points to HRTB, and what HIR allows.
         // ```
         // fn foo(x: impl for<'a> Trait<'a, Assoc = impl Copy + 'a>) {}
diff --git a/compiler/rustc_hir_analysis/src/collect/type_of.rs b/compiler/rustc_hir_analysis/src/collect/type_of.rs
index c173bd913a8..d7d509e5394 100644
--- a/compiler/rustc_hir_analysis/src/collect/type_of.rs
+++ b/compiler/rustc_hir_analysis/src/collect/type_of.rs
@@ -1,6 +1,6 @@
 use rustc_errors::{Applicability, StashKey};
 use rustc_hir as hir;
-use rustc_hir::def_id::{DefId, LocalDefId};
+use rustc_hir::def_id::LocalDefId;
 use rustc_hir::intravisit;
 use rustc_hir::intravisit::Visitor;
 use rustc_hir::{HirId, Node};
@@ -16,22 +16,81 @@ use super::ItemCtxt;
 use super::{bad_placeholder, is_suggestable_infer_ty};
 use crate::errors::UnconstrainedOpaqueType;
 
-/// Computes the relevant generic parameter for a potential generic const argument.
-///
-/// This should be called using the query `tcx.opt_const_param_of`.
-pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<DefId> {
+fn anon_const_type_of<'tcx>(tcx: TyCtxt<'tcx>, def_id: LocalDefId) -> Ty<'tcx> {
     use hir::*;
     let hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
 
-    match tcx.hir().get(hir_id) {
-        Node::AnonConst(_) => (),
-        _ => return None,
-    };
+    let Node::AnonConst(_) = tcx.hir().get(hir_id) else { panic!() };
 
     let parent_node_id = tcx.hir().parent_id(hir_id);
     let parent_node = tcx.hir().get(parent_node_id);
 
     let (generics, arg_idx) = match parent_node {
+        // Easy case: arrays repeat expressions.
+        Node::Ty(&Ty { kind: TyKind::Array(_, ref constant), .. })
+        | Node::Expr(&Expr { kind: ExprKind::Repeat(_, ref constant), .. })
+            if constant.hir_id() == hir_id =>
+        {
+            return tcx.types.usize
+        }
+        Node::Ty(&Ty { kind: TyKind::Typeof(ref e), .. }) if e.hir_id == hir_id => {
+            return tcx.typeck(def_id).node_type(e.hir_id)
+        }
+        Node::Expr(&Expr { kind: ExprKind::ConstBlock(ref anon_const), .. })
+            if anon_const.hir_id == hir_id =>
+        {
+            let substs = InternalSubsts::identity_for_item(tcx, def_id.to_def_id());
+            return substs.as_inline_const().ty()
+        }
+        Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
+        | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
+            if asm.operands.iter().any(|(op, _op_sp)| match op {
+                hir::InlineAsmOperand::Const { anon_const }
+                | hir::InlineAsmOperand::SymFn { anon_const } => anon_const.hir_id == hir_id,
+                _ => false,
+            }) =>
+        {
+            return tcx.typeck(def_id).node_type(hir_id)
+        }
+        Node::Variant(Variant { disr_expr: Some(ref e), .. }) if e.hir_id == hir_id => {
+            return tcx
+                .adt_def(tcx.hir().get_parent_item(hir_id))
+                .repr()
+                .discr_type()
+                .to_ty(tcx)
+        }
+        Node::GenericParam(&GenericParam {
+            def_id: param_def_id,
+            kind: GenericParamKind::Const { default: Some(ct), .. },
+            ..
+        }) if ct.hir_id == hir_id => {
+            return tcx.type_of(param_def_id)
+                .no_bound_vars()
+                .expect("const parameter types cannot be generic")
+        }
+
+        Node::TypeBinding(binding @ &TypeBinding { hir_id: binding_id, ..  })
+            if let Node::TraitRef(trait_ref) = tcx.hir().get(
+                tcx.hir().parent_id(binding_id)
+            ) =>
+        {
+            let Some(trait_def_id) = trait_ref.trait_def_id() else {
+                return tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find trait");
+            };
+            let assoc_items = tcx.associated_items(trait_def_id);
+            let assoc_item = assoc_items.find_by_name_and_kind(
+                tcx, binding.ident, ty::AssocKind::Const, def_id.to_def_id(),
+            );
+            return if let Some(assoc_item) = assoc_item {
+                tcx.type_of(assoc_item.def_id)
+                    .no_bound_vars()
+                    .expect("const parameter types cannot be generic")
+            } else {
+                // FIXME(associated_const_equality): add a useful error message here.
+                tcx.ty_error_with_message(tcx.def_span(def_id), "Could not find associated const on trait")
+            }
+        }
+
         // This match arm is for when the def_id appears in a GAT whose
         // path can't be resolved without typechecking e.g.
         //
@@ -86,11 +145,10 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                 (generics, arg_index)
             } else {
                 // I dont think it's possible to reach this but I'm not 100% sure - BoxyUwU
-                tcx.sess.delay_span_bug(
+                return tcx.ty_error_with_message(
                     tcx.def_span(def_id),
                     "unexpected non-GAT usage of an anon const",
                 );
-                return None;
             }
         }
         Node::Expr(&Expr {
@@ -103,7 +161,12 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             // This may fail in case the method/path does not actually exist.
             // As there is no relevant param for `def_id`, we simply return
             // `None` here.
-            let type_dependent_def = tables.type_dependent_def_id(parent_node_id)?;
+            let Some(type_dependent_def) = tables.type_dependent_def_id(parent_node_id) else {
+                return tcx.ty_error_with_message(
+                    tcx.def_span(def_id),
+                    &format!("unable to find type-dependent def for {:?}", parent_node_id),
+                );
+            };
             let idx = segment
                 .args
                 .and_then(|args| {
@@ -140,19 +203,17 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                     if let Some(path) = get_path_containing_arg_in_pat(pat, hir_id) {
                         path
                     } else {
-                        tcx.sess.delay_span_bug(
+                        return tcx.ty_error_with_message(
                             tcx.def_span(def_id),
                             &format!("unable to find const parent for {} in pat {:?}", hir_id, pat),
                         );
-                        return None;
                     }
                 }
                 _ => {
-                    tcx.sess.delay_span_bug(
+                    return tcx.ty_error_with_message(
                         tcx.def_span(def_id),
                         &format!("unexpected const parent path {:?}", parent_node),
                     );
-                    return None;
                 }
             };
 
@@ -171,32 +232,34 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
                     .position(|ct| ct.hir_id == hir_id)
                     .map(|idx| (idx, seg)))
             }) else {
-                tcx.sess.delay_span_bug(
+                return tcx.ty_error_with_message(
                     tcx.def_span(def_id),
                     "no arg matching AnonConst in path",
                 );
-                return None;
             };
 
             let generics = match tcx.res_generics_def_id(segment.res) {
                 Some(def_id) => tcx.generics_of(def_id),
                 None => {
-                    tcx.sess.delay_span_bug(
+                    return tcx.ty_error_with_message(
                         tcx.def_span(def_id),
                         &format!("unexpected anon const res {:?} in path: {:?}", segment.res, path),
                     );
-                    return None;
                 }
             };
 
             (generics, arg_index)
         }
-        _ => return None,
+
+        _ => return tcx.ty_error_with_message(
+            tcx.def_span(def_id),
+            &format!("unexpected const parent in type_of(): {parent_node:?}"),
+        ),
     };
 
     debug!(?parent_node);
     debug!(?generics, ?arg_idx);
-    generics
+    if let Some(param_def_id) = generics
         .params
         .iter()
         .filter(|param| param.kind.is_ty_or_const())
@@ -211,6 +274,14 @@ pub(super) fn opt_const_param_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<
             }
             _ => None,
         })
+    {
+        tcx.type_of(param_def_id).no_bound_vars().expect("const parameter types cannot be generic")
+    } else {
+        return tcx.ty_error_with_message(
+            tcx.def_span(def_id),
+            &format!("const generic parameter not found in {generics:?} at position {arg_idx:?}"),
+        );
+    }
 }
 
 fn get_path_containing_arg_in_pat<'hir>(
@@ -251,7 +322,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
         match tcx.collect_return_position_impl_trait_in_trait_tys(fn_def_id) {
             Ok(map) => {
                 let assoc_item = tcx.associated_item(def_id);
-                return ty::EarlyBinder(map[&assoc_item.trait_item_def_id.unwrap()]);
+                return map[&assoc_item.trait_item_def_id.unwrap()];
             }
             Err(_) => {
                 return ty::EarlyBinder(tcx.ty_error_with_message(
@@ -415,143 +486,7 @@ pub(super) fn type_of(tcx: TyCtxt<'_>, def_id: LocalDefId) -> ty::EarlyBinder<Ty
             tcx.typeck(def_id).node_type(hir_id)
         }
 
-        Node::AnonConst(_) if let Some(param) = tcx.opt_const_param_of(def_id) => {
-            // We defer to `type_of` of the corresponding parameter
-            // for generic arguments.
-            tcx.type_of(param).subst_identity()
-        }
-
-        Node::AnonConst(_) => {
-            let parent_node = tcx.hir().get_parent(hir_id);
-            match parent_node {
-                Node::Ty(Ty { kind: TyKind::Array(_, constant), .. })
-                | Node::Expr(Expr { kind: ExprKind::Repeat(_, constant), .. })
-                    if constant.hir_id() == hir_id =>
-                {
-                    tcx.types.usize
-                }
-                Node::Ty(Ty { kind: TyKind::Typeof(e), .. }) if e.hir_id == hir_id => {
-                    tcx.typeck(def_id).node_type(e.hir_id)
-                }
-
-                Node::Expr(Expr { kind: ExprKind::ConstBlock(anon_const), .. })
-                    if anon_const.hir_id == hir_id =>
-                {
-                    let substs = InternalSubsts::identity_for_item(tcx, def_id);
-                    substs.as_inline_const().ty()
-                }
-
-                Node::Expr(&Expr { kind: ExprKind::InlineAsm(asm), .. })
-                | Node::Item(&Item { kind: ItemKind::GlobalAsm(asm), .. })
-                    if asm.operands.iter().any(|(op, _op_sp)| match op {
-                        hir::InlineAsmOperand::Const { anon_const }
-                        | hir::InlineAsmOperand::SymFn { anon_const } => {
-                            anon_const.hir_id == hir_id
-                        }
-                        _ => false,
-                    }) =>
-                {
-                    tcx.typeck(def_id).node_type(hir_id)
-                }
-
-                Node::Variant(Variant { disr_expr: Some(e), .. }) if e.hir_id == hir_id => {
-                    tcx.adt_def(tcx.hir().get_parent_item(hir_id)).repr().discr_type().to_ty(tcx)
-                }
-
-                Node::TypeBinding(TypeBinding {
-                    hir_id: binding_id,
-                    kind: TypeBindingKind::Equality { term: Term::Const(e) },
-                    ident,
-                    ..
-                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
-                    && e.hir_id == hir_id =>
-                {
-                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
-                        return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
-                    };
-                    let assoc_items = tcx.associated_items(trait_def_id);
-                    let assoc_item = assoc_items.find_by_name_and_kind(
-                        tcx,
-                        *ident,
-                        ty::AssocKind::Const,
-                        def_id.to_def_id(),
-                    );
-                    if let Some(assoc_item) = assoc_item {
-                        tcx.type_of(assoc_item.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic")
-                    } else {
-                        // FIXME(associated_const_equality): add a useful error message here.
-                        tcx.ty_error_with_message(
-                            DUMMY_SP,
-                            "Could not find associated const on trait",
-                        )
-                    }
-                }
-
-                Node::TypeBinding(TypeBinding {
-                    hir_id: binding_id,
-                    gen_args,
-                    kind,
-                    ident,
-                    ..
-                }) if let Node::TraitRef(trait_ref) = tcx.hir().get_parent(*binding_id)
-                    && let Some((idx, _)) =
-                        gen_args.args.iter().enumerate().find(|(_, arg)| {
-                            if let GenericArg::Const(ct) = arg {
-                                ct.value.hir_id == hir_id
-                            } else {
-                                false
-                            }
-                        }) =>
-                {
-                    let Some(trait_def_id) = trait_ref.trait_def_id() else {
-                        return ty::EarlyBinder(tcx.ty_error_with_message(DUMMY_SP, "Could not find trait"));
-                    };
-                    let assoc_items = tcx.associated_items(trait_def_id);
-                    let assoc_item = assoc_items.find_by_name_and_kind(
-                        tcx,
-                        *ident,
-                        match kind {
-                            // I think `<A: T>` type bindings requires that `A` is a type
-                            TypeBindingKind::Constraint { .. }
-                            | TypeBindingKind::Equality { term: Term::Ty(..) } => {
-                                ty::AssocKind::Type
-                            }
-                            TypeBindingKind::Equality { term: Term::Const(..) } => {
-                                ty::AssocKind::Const
-                            }
-                        },
-                        def_id.to_def_id(),
-                    );
-                    if let Some(assoc_item) = assoc_item
-                        && let param = &tcx.generics_of(assoc_item.def_id).params[idx]
-                        && matches!(param.kind, ty::GenericParamDefKind::Const { .. })
-                    {
-                        tcx.type_of(param.def_id)
-                            .no_bound_vars()
-                            .expect("const parameter types cannot be generic")
-                    } else {
-                        // FIXME(associated_const_equality): add a useful error message here.
-                        tcx.ty_error_with_message(
-                            DUMMY_SP,
-                            "Could not find const param on associated item",
-                        )
-                    }
-                }
-
-                Node::GenericParam(&GenericParam {
-                    def_id: param_def_id,
-                    kind: GenericParamKind::Const { default: Some(ct), .. },
-                    ..
-                }) if ct.hir_id == hir_id => tcx.type_of(param_def_id).subst_identity(),
-
-                x => tcx.ty_error_with_message(
-                    DUMMY_SP,
-                    &format!("unexpected const parent in type_of(): {x:?}"),
-                ),
-            }
-        }
+        Node::AnonConst(_) => anon_const_type_of(tcx, def_id),
 
         Node::GenericParam(param) => match &param.kind {
             GenericParamKind::Type { default: Some(ty), .. }
diff --git a/compiler/rustc_hir_analysis/src/lib.rs b/compiler/rustc_hir_analysis/src/lib.rs
index 27e56180349..a4b797f77f7 100644
--- a/compiler/rustc_hir_analysis/src/lib.rs
+++ b/compiler/rustc_hir_analysis/src/lib.rs
@@ -99,10 +99,10 @@ mod variance;
 
 use rustc_errors::ErrorGuaranteed;
 use rustc_errors::{DiagnosticMessage, SubdiagnosticMessage};
+use rustc_fluent_macro::fluent_messages;
 use rustc_hir as hir;
 use rustc_hir::Node;
 use rustc_infer::infer::TyCtxtInferExt;
-use rustc_macros::fluent_messages;
 use rustc_middle::middle;
 use rustc_middle::ty::query::Providers;
 use rustc_middle::ty::{self, Ty, TyCtxt};
@@ -496,8 +496,6 @@ pub fn check_crate(tcx: TyCtxt<'_>) -> Result<(), ErrorGuaranteed> {
         tcx.hir().for_each_module(|module| tcx.ensure().check_mod_item_types(module))
     });
 
-    tcx.sess.time("item_bodies_checking", || tcx.typeck_item_bodies(()));
-
     check_unused::check_crate(tcx);
     check_for_entry_fn(tcx);
 
diff --git a/compiler/rustc_hir_analysis/src/variance/constraints.rs b/compiler/rustc_hir_analysis/src/variance/constraints.rs
index 408bec71ee0..6f0afae1b4c 100644
--- a/compiler/rustc_hir_analysis/src/variance/constraints.rs
+++ b/compiler/rustc_hir_analysis/src/variance/constraints.rs
@@ -92,7 +92,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
     fn build_constraints_for_item(&mut self, def_id: LocalDefId) {
         let tcx = self.tcx();
-        debug!("build_constraints_for_item({})", tcx.def_path_str(def_id.to_def_id()));
+        debug!("build_constraints_for_item({})", tcx.def_path_str(def_id));
 
         // Skip items with no generics - there's nothing to infer in them.
         if tcx.generics_of(def_id).count() == 0 {
diff --git a/compiler/rustc_hir_analysis/src/variance/mod.rs b/compiler/rustc_hir_analysis/src/variance/mod.rs
index 0a45119ff05..4d240e90b14 100644
--- a/compiler/rustc_hir_analysis/src/variance/mod.rs
+++ b/compiler/rustc_hir_analysis/src/variance/mod.rs
@@ -105,7 +105,7 @@ fn variance_of_opaque(tcx: TyCtxt<'_>, item_def_id: LocalDefId) -> &[ty::Varianc
             if let ty::RegionKind::ReEarlyBound(ebr) = r.kind() {
                 self.variances[ebr.index as usize] = ty::Invariant;
             }
-            r.super_visit_with(self)
+            ControlFlow::Continue(())
         }
 
         #[instrument(level = "trace", skip(self), ret)]