about summary refs log tree commit diff
diff options
context:
space:
mode:
authorLukas Wirth <lukastw97@gmail.com>2024-04-06 13:12:07 +0200
committerLukas Wirth <lukastw97@gmail.com>2024-04-06 13:12:07 +0200
commit13890697ebb6d4f566c4236d82daa8deedda7ea1 (patch)
tree055689bf2dcb1751c7ae77c8b99d40a24250defc
parent6a852d7627871dd98d9e2c1e2b96b04a05a62183 (diff)
downloadrust-13890697ebb6d4f566c4236d82daa8deedda7ea1.tar.gz
rust-13890697ebb6d4f566c4236d82daa8deedda7ea1.zip
Simplify
-rw-r--r--crates/base-db/src/input.rs1
-rw-r--r--crates/hir-def/src/data.rs2
-rw-r--r--crates/hir-def/src/expander.rs8
-rw-r--r--crates/hir-ty/src/consteval.rs33
-rw-r--r--crates/hir-ty/src/infer.rs6
-rw-r--r--crates/hir-ty/src/infer/cast.rs4
-rw-r--r--crates/hir-ty/src/infer/closure.rs16
-rw-r--r--crates/hir-ty/src/infer/expr.rs20
-rw-r--r--crates/hir-ty/src/infer/pat.rs48
-rw-r--r--crates/hir-ty/src/lower.rs104
-rw-r--r--crates/hir-ty/src/utils.rs10
-rw-r--r--crates/limit/Cargo.toml3
12 files changed, 120 insertions, 135 deletions
diff --git a/crates/base-db/src/input.rs b/crates/base-db/src/input.rs
index 27eb05cd4dc..6ea1e676a13 100644
--- a/crates/base-db/src/input.rs
+++ b/crates/base-db/src/input.rs
@@ -285,6 +285,7 @@ pub struct CrateData {
     /// For purposes of analysis, crates are anonymous (only names in
     /// `Dependency` matters), this name should only be used for UI.
     pub display_name: Option<CrateDisplayName>,
+    // FIXME: Arc this
     pub cfg_options: CfgOptions,
     /// The cfg options that could be used by the crate
     pub potential_cfg_options: Option<CfgOptions>,
diff --git a/crates/hir-def/src/data.rs b/crates/hir-def/src/data.rs
index da790f11516..b5317be288e 100644
--- a/crates/hir-def/src/data.rs
+++ b/crates/hir-def/src/data.rs
@@ -737,7 +737,7 @@ impl<'a> AssocItemCollector<'a> {
                     &AstIdWithPath::new(file_id, ast_id, Clone::clone(path)),
                     ctxt,
                     expand_to,
-                    self.expander.module.krate(),
+                    self.expander.krate(),
                     resolver,
                 ) {
                     Ok(Some(call_id)) => {
diff --git a/crates/hir-def/src/expander.rs b/crates/hir-def/src/expander.rs
index b0872fcdc0e..3084e06c1be 100644
--- a/crates/hir-def/src/expander.rs
+++ b/crates/hir-def/src/expander.rs
@@ -21,7 +21,6 @@ use crate::{
 pub struct Expander {
     cfg_options: CfgOptions,
     span_map: OnceCell<SpanMap>,
-    krate: CrateId,
     current_file_id: HirFileId,
     pub(crate) module: ModuleId,
     /// `recursion_depth == usize::MAX` indicates that the recursion limit has been reached.
@@ -45,10 +44,13 @@ impl Expander {
             recursion_limit,
             cfg_options: db.crate_graph()[module.krate].cfg_options.clone(),
             span_map: OnceCell::new(),
-            krate: module.krate,
         }
     }
 
+    pub fn krate(&self) -> CrateId {
+        self.module.krate
+    }
+
     pub fn enter_expand<T: ast::AstNode>(
         &mut self,
         db: &dyn DefDatabase,
@@ -112,7 +114,7 @@ impl Expander {
     pub(crate) fn parse_attrs(&self, db: &dyn DefDatabase, owner: &dyn ast::HasAttrs) -> Attrs {
         Attrs::filter(
             db,
-            self.krate,
+            self.krate(),
             RawAttrs::new(
                 db.upcast(),
                 owner,
diff --git a/crates/hir-ty/src/consteval.rs b/crates/hir-ty/src/consteval.rs
index 705609ba68d..eb5c2c55041 100644
--- a/crates/hir-ty/src/consteval.rs
+++ b/crates/hir-ty/src/consteval.rs
@@ -77,30 +77,32 @@ pub(crate) fn path_to_const(
     resolver: &Resolver,
     path: &Path,
     mode: ParamLoweringMode,
-    args_lazy: impl FnOnce() -> Generics,
+    args: impl FnOnce() -> Option<Generics>,
     debruijn: DebruijnIndex,
     expected_ty: Ty,
 ) -> Option<Const> {
     match resolver.resolve_path_in_value_ns_fully(db.upcast(), path) {
         Some(ValueNs::GenericParam(p)) => {
             let ty = db.const_param_ty(p);
-            let args = args_lazy();
             let value = match mode {
                 ParamLoweringMode::Placeholder => {
                     ConstValue::Placeholder(to_placeholder_idx(db, p.into()))
                 }
-                ParamLoweringMode::Variable => match args.param_idx(p.into()) {
-                    Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
-                    None => {
-                        never!(
-                            "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
-                            args,
-                            path,
-                            p
-                        );
-                        return None;
+                ParamLoweringMode::Variable => {
+                    let args = args();
+                    match args.as_ref().and_then(|args| args.param_idx(p.into())) {
+                        Some(it) => ConstValue::BoundVar(BoundVar::new(debruijn, it)),
+                        None => {
+                            never!(
+                                "Generic list doesn't contain this param: {:?}, {:?}, {:?}",
+                                args,
+                                path,
+                                p
+                            );
+                            return None;
+                        }
                     }
-                },
+                }
             };
             Some(ConstData { ty, value }.intern(Interner))
         }
@@ -285,7 +287,6 @@ pub(crate) fn eval_to_const(
     expr: ExprId,
     mode: ParamLoweringMode,
     ctx: &mut InferenceContext<'_>,
-    args: impl FnOnce() -> Generics,
     debruijn: DebruijnIndex,
 ) -> Const {
     let db = ctx.db;
@@ -304,7 +305,9 @@ pub(crate) fn eval_to_const(
     }
     if let Expr::Path(p) = &ctx.body.exprs[expr] {
         let resolver = &ctx.resolver;
-        if let Some(c) = path_to_const(db, resolver, p, mode, args, debruijn, infer[expr].clone()) {
+        if let Some(c) =
+            path_to_const(db, resolver, p, mode, || ctx.generics(), debruijn, infer[expr].clone())
+        {
             return c;
         }
     }
diff --git a/crates/hir-ty/src/infer.rs b/crates/hir-ty/src/infer.rs
index 3b644379fa6..3aacf7d07f9 100644
--- a/crates/hir-ty/src/infer.rs
+++ b/crates/hir-ty/src/infer.rs
@@ -60,7 +60,7 @@ use crate::{
     lower::ImplTraitLoweringMode,
     to_assoc_type_id,
     traits::FnTrait,
-    utils::{InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
+    utils::{Generics, InTypeConstIdMetadata, UnevaluatedConstEvaluatorFolder},
     AliasEq, AliasTy, Binders, ClosureId, Const, DomainGoal, GenericArg, Goal, ImplTraitId,
     ImplTraitIdx, InEnvironment, Interner, Lifetime, OpaqueTyId, ProjectionTy, Substitution,
     TraitEnvironment, Ty, TyBuilder, TyExt,
@@ -630,6 +630,10 @@ impl<'a> InferenceContext<'a> {
         }
     }
 
+    pub(crate) fn generics(&self) -> Option<Generics> {
+        Some(crate::utils::generics(self.db.upcast(), self.resolver.generic_def()?))
+    }
+
     // FIXME: This function should be private in module. It is currently only used in the consteval, since we need
     // `InferenceResult` in the middle of inference. See the fixme comment in `consteval::eval_to_const`. If you
     // used this function for another workaround, mention it here. If you really need this function and believe that
diff --git a/crates/hir-ty/src/infer/cast.rs b/crates/hir-ty/src/infer/cast.rs
index f8c03ee2886..060b5f36f29 100644
--- a/crates/hir-ty/src/infer/cast.rs
+++ b/crates/hir-ty/src/infer/cast.rs
@@ -19,10 +19,6 @@ impl CastCheck {
         let expr_ty = table.resolve_ty_shallow(&self.expr_ty);
         let cast_ty = table.resolve_ty_shallow(&self.cast_ty);
 
-        if expr_ty.contains_unknown() || cast_ty.contains_unknown() {
-            return;
-        }
-
         if table.coerce(&expr_ty, &cast_ty).is_ok() {
             return;
         }
diff --git a/crates/hir-ty/src/infer/closure.rs b/crates/hir-ty/src/infer/closure.rs
index 20d24e6fe2e..f08c0b68716 100644
--- a/crates/hir-ty/src/infer/closure.rs
+++ b/crates/hir-ty/src/infer/closure.rs
@@ -26,7 +26,7 @@ use crate::{
     mir::{BorrowKind, MirSpan, MutBorrowKind, ProjectionElem},
     to_chalk_trait_id,
     traits::FnTrait,
-    utils::{self, elaborate_clause_supertraits, generics, Generics},
+    utils::{self, elaborate_clause_supertraits, Generics},
     Adjust, Adjustment, AliasEq, AliasTy, Binders, BindingMode, ChalkTraitId, ClosureId, DynTy,
     DynTyExt, FnAbi, FnPointer, FnSig, Interner, OpaqueTy, ProjectionTyExt, Substitution, Ty,
     TyExt, WhereClause,
@@ -331,14 +331,10 @@ impl CapturedItemWithoutTy {
             place: self.place,
             kind: self.kind,
             span: self.span,
-            ty: replace_placeholder_with_binder(ctx.db, ctx.owner, ty),
+            ty: replace_placeholder_with_binder(ctx, ty),
         };
 
-        fn replace_placeholder_with_binder(
-            db: &dyn HirDatabase,
-            owner: DefWithBodyId,
-            ty: Ty,
-        ) -> Binders<Ty> {
+        fn replace_placeholder_with_binder(ctx: &mut InferenceContext<'_>, ty: Ty) -> Binders<Ty> {
             struct Filler<'a> {
                 db: &'a dyn HirDatabase,
                 generics: Generics,
@@ -379,12 +375,12 @@ impl CapturedItemWithoutTy {
                     Ok(BoundVar::new(outer_binder, idx).to_ty(Interner))
                 }
             }
-            let Some(generic_def) = owner.as_generic_def_id() else {
+            let Some(generics) = ctx.generics() else {
                 return Binders::empty(Interner, ty);
             };
-            let filler = &mut Filler { db, generics: generics(db.upcast(), generic_def) };
+            let filler = &mut Filler { db: ctx.db, generics };
             let result = ty.clone().try_fold_with(filler, DebruijnIndex::INNERMOST).unwrap_or(ty);
-            make_binders(db, &filler.generics, result)
+            make_binders(ctx.db, &filler.generics, result)
         }
     }
 }
diff --git a/crates/hir-ty/src/infer/expr.rs b/crates/hir-ty/src/infer/expr.rs
index 4d3d7376c4d..d011a62e77a 100644
--- a/crates/hir-ty/src/infer/expr.rs
+++ b/crates/hir-ty/src/infer/expr.rs
@@ -1040,18 +1040,12 @@ impl InferenceContext<'_> {
 
                 (
                     elem_ty,
-                    if let Some(g_def) = self.owner.as_generic_def_id() {
-                        let generics = generics(self.db.upcast(), g_def);
-                        consteval::eval_to_const(
-                            repeat,
-                            ParamLoweringMode::Placeholder,
-                            self,
-                            || generics,
-                            DebruijnIndex::INNERMOST,
-                        )
-                    } else {
-                        consteval::usize_const(self.db, None, krate)
-                    },
+                    consteval::eval_to_const(
+                        repeat,
+                        ParamLoweringMode::Placeholder,
+                        self,
+                        DebruijnIndex::INNERMOST,
+                    ),
                 )
             }
         };
@@ -1852,7 +1846,7 @@ impl InferenceContext<'_> {
                             ty,
                             c,
                             ParamLoweringMode::Placeholder,
-                            || generics(this.db.upcast(), this.resolver.generic_def().unwrap()),
+                            || this.generics(),
                             DebruijnIndex::INNERMOST,
                         )
                     },
diff --git a/crates/hir-ty/src/infer/pat.rs b/crates/hir-ty/src/infer/pat.rs
index 440ffa33572..1b354935a5b 100644
--- a/crates/hir-ty/src/infer/pat.rs
+++ b/crates/hir-ty/src/infer/pat.rs
@@ -2,13 +2,13 @@
 
 use std::iter::repeat_with;
 
-use chalk_ir::Mutability;
 use hir_def::{
     body::Body,
     hir::{Binding, BindingAnnotation, BindingId, Expr, ExprId, ExprOrPatId, Literal, Pat, PatId},
     path::Path,
 };
 use hir_expand::name::Name;
+use stdx::TupleExt;
 
 use crate::{
     consteval::{try_const_usize, usize_const},
@@ -16,8 +16,8 @@ use crate::{
     infer::{BindingMode, Expectation, InferenceContext, TypeMismatch},
     lower::lower_to_chalk_mutability,
     primitive::UintTy,
-    static_lifetime, InferenceDiagnostic, Interner, Scalar, Substitution, Ty, TyBuilder, TyExt,
-    TyKind,
+    static_lifetime, InferenceDiagnostic, Interner, Mutability, Scalar, Substitution, Ty,
+    TyBuilder, TyExt, TyKind,
 };
 
 /// Used to generalize patterns and assignee expressions.
@@ -90,9 +90,6 @@ impl InferenceContext<'_> {
 
         self.unify(&ty, expected);
 
-        let substs =
-            ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
         match def {
             _ if subs.is_empty() => {}
             Some(def) => {
@@ -109,8 +106,10 @@ impl InferenceContext<'_> {
                 let pre_iter = pre.iter().enumerate();
                 let post_iter = (post_idx_offset..).zip(post.iter());
 
+                let substs = ty.as_adt().map(TupleExt::tail);
+
                 for (i, &subpat) in pre_iter.chain(post_iter) {
-                    let field_def = {
+                    let expected_ty = {
                         match variant_data.field(&Name::new_tuple_field(i)) {
                             Some(local_id) => {
                                 if !visibilities[local_id]
@@ -118,17 +117,17 @@ impl InferenceContext<'_> {
                                 {
                                     // FIXME(DIAGNOSE): private tuple field
                                 }
-                                Some(local_id)
+                                let f = field_types[local_id].clone();
+                                let expected_ty = match substs {
+                                    Some(substs) => f.substitute(Interner, substs),
+                                    None => f.substitute(Interner, &Substitution::empty(Interner)),
+                                };
+                                self.normalize_associated_types_in(expected_ty)
                             }
-                            None => None,
+                            None => self.err_ty(),
                         }
                     };
 
-                    let expected_ty = field_def.map_or(self.err_ty(), |f| {
-                        field_types[f].clone().substitute(Interner, &substs)
-                    });
-                    let expected_ty = self.normalize_associated_types_in(expected_ty);
-
                     T::infer(self, subpat, &expected_ty, default_bm);
                 }
             }
@@ -159,9 +158,6 @@ impl InferenceContext<'_> {
 
         self.unify(&ty, expected);
 
-        let substs =
-            ty.as_adt().map(|(_, s)| s.clone()).unwrap_or_else(|| Substitution::empty(Interner));
-
         match def {
             _ if subs.len() == 0 => {}
             Some(def) => {
@@ -169,8 +165,10 @@ impl InferenceContext<'_> {
                 let variant_data = def.variant_data(self.db.upcast());
                 let visibilities = self.db.field_visibilities(def);
 
+                let substs = ty.as_adt().map(TupleExt::tail);
+
                 for (name, inner) in subs {
-                    let field_def = {
+                    let expected_ty = {
                         match variant_data.field(&name) {
                             Some(local_id) => {
                                 if !visibilities[local_id]
@@ -181,23 +179,23 @@ impl InferenceContext<'_> {
                                         private: true,
                                     });
                                 }
-                                Some(local_id)
+                                let f = field_types[local_id].clone();
+                                let expected_ty = match substs {
+                                    Some(substs) => f.substitute(Interner, substs),
+                                    None => f.substitute(Interner, &Substitution::empty(Interner)),
+                                };
+                                self.normalize_associated_types_in(expected_ty)
                             }
                             None => {
                                 self.push_diagnostic(InferenceDiagnostic::NoSuchField {
                                     field: inner.into(),
                                     private: false,
                                 });
-                                None
+                                self.err_ty()
                             }
                         }
                     };
 
-                    let expected_ty = field_def.map_or(self.err_ty(), |f| {
-                        field_types[f].clone().substitute(Interner, &substs)
-                    });
-                    let expected_ty = self.normalize_associated_types_in(expected_ty);
-
                     T::infer(self, inner, &expected_ty, default_bm);
                 }
             }
diff --git a/crates/hir-ty/src/lower.rs b/crates/hir-ty/src/lower.rs
index 9a468e2a233..a4ab1ebb8b9 100644
--- a/crates/hir-ty/src/lower.rs
+++ b/crates/hir-ty/src/lower.rs
@@ -62,8 +62,8 @@ use crate::{
     mapping::{from_chalk_trait_id, lt_to_placeholder_idx, ToChalk},
     static_lifetime, to_assoc_type_id, to_chalk_trait_id, to_placeholder_idx,
     utils::{
-        all_super_trait_refs, associated_type_by_name_including_super_traits, generics, Generics,
-        InTypeConstIdMetadata,
+        self, all_super_trait_refs, associated_type_by_name_including_super_traits, generics,
+        Generics, InTypeConstIdMetadata,
     },
     AliasEq, AliasTy, Binders, BoundVar, CallableSig, Const, ConstScalar, DebruijnIndex, DynTy,
     FnAbi, FnPointer, FnSig, FnSubst, ImplTrait, ImplTraitId, ImplTraits, Interner, Lifetime,
@@ -245,13 +245,8 @@ impl<'a> TyLoweringContext<'a> {
         )
     }
 
-    fn generics(&self) -> Generics {
-        generics(
-            self.db.upcast(),
-            self.resolver
-                .generic_def()
-                .expect("there should be generics if there's a generic param"),
-        )
+    fn generics(&self) -> Option<Generics> {
+        Some(generics(self.db.upcast(), self.resolver.generic_def()?))
     }
 
     pub fn lower_ty_ext(&self, type_ref: &TypeRef) -> (Ty, Option<TypeNs>) {
@@ -352,8 +347,7 @@ impl<'a> TyLoweringContext<'a> {
                         let idx = counter.get();
                         // FIXME we're probably doing something wrong here
                         counter.set(idx + count_impl_traits(type_ref) as u16);
-                        if let Some(def) = self.resolver.generic_def() {
-                            let generics = generics(self.db.upcast(), def);
+                        if let Some(generics) = self.generics() {
                             let param = generics
                                 .iter()
                                 .filter(|(_, data)| {
@@ -388,8 +382,7 @@ impl<'a> TyLoweringContext<'a> {
                             const_params,
                             _impl_trait_params,
                             _lifetime_params,
-                        ) = if let Some(def) = self.resolver.generic_def() {
-                            let generics = generics(self.db.upcast(), def);
+                        ) = if let Some(generics) = self.generics() {
                             generics.provenance_split()
                         } else {
                             (0, 0, 0, 0, 0, 0)
@@ -577,44 +570,40 @@ impl<'a> TyLoweringContext<'a> {
                 // FIXME(trait_alias): Implement trait alias.
                 return (TyKind::Error.intern(Interner), None);
             }
-            TypeNs::GenericParam(param_id) => {
-                let generics = generics(
-                    self.db.upcast(),
-                    self.resolver.generic_def().expect("generics in scope"),
-                );
-                match self.type_param_mode {
-                    ParamLoweringMode::Placeholder => {
-                        TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
-                    }
-                    ParamLoweringMode::Variable => {
-                        let idx = match generics.param_idx(param_id.into()) {
-                            None => {
-                                never!("no matching generics");
-                                return (TyKind::Error.intern(Interner), None);
-                            }
-                            Some(idx) => idx,
-                        };
+            TypeNs::GenericParam(param_id) => match self.type_param_mode {
+                ParamLoweringMode::Placeholder => {
+                    TyKind::Placeholder(to_placeholder_idx(self.db, param_id.into()))
+                }
+                ParamLoweringMode::Variable => {
+                    let idx = match self
+                        .generics()
+                        .expect("generics in scope")
+                        .param_idx(param_id.into())
+                    {
+                        None => {
+                            never!("no matching generics");
+                            return (TyKind::Error.intern(Interner), None);
+                        }
+                        Some(idx) => idx,
+                    };
 
-                        TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
-                    }
+                    TyKind::BoundVar(BoundVar::new(self.in_binders, idx))
                 }
-                .intern(Interner)
             }
+            .intern(Interner),
             TypeNs::SelfType(impl_id) => {
-                let def =
-                    self.resolver.generic_def().expect("impl should have generic param scope");
-                let generics = generics(self.db.upcast(), def);
+                let generics = self.generics().expect("impl should have generic param scope");
 
                 match self.type_param_mode {
                     ParamLoweringMode::Placeholder => {
                         // `def` can be either impl itself or item within, and we need impl itself
                         // now.
-                        let generics = generics.parent_generics().unwrap_or(&generics);
+                        let generics = generics.parent_or_self();
                         let subst = generics.placeholder_subst(self.db);
                         self.db.impl_self_ty(impl_id).substitute(Interner, &subst)
                     }
                     ParamLoweringMode::Variable => {
-                        let starting_from = match def {
+                        let starting_from = match generics.def() {
                             GenericDefId::ImplId(_) => 0,
                             // `def` is an item within impl. We need to substitute `BoundVar`s but
                             // remember that they are for parent (i.e. impl) generic params so they
@@ -682,12 +671,12 @@ impl<'a> TyLoweringContext<'a> {
     }
 
     fn select_associated_type(&self, res: Option<TypeNs>, segment: PathSegment<'_>) -> Ty {
-        let Some((def, res)) = self.resolver.generic_def().zip(res) else {
+        let Some((generics, res)) = self.generics().zip(res) else {
             return TyKind::Error.intern(Interner);
         };
         let ty = named_associated_type_shorthand_candidates(
             self.db,
-            def,
+            generics.def(),
             res,
             Some(segment.name.clone()),
             move |name, t, associated_ty| {
@@ -699,7 +688,6 @@ impl<'a> TyLoweringContext<'a> {
                 let parent_subst = match self.type_param_mode {
                     ParamLoweringMode::Placeholder => {
                         // if we're lowering to placeholders, we have to put them in now.
-                        let generics = generics(self.db.upcast(), def);
                         let s = generics.placeholder_subst(self.db);
                         s.apply(parent_subst, Interner)
                     }
@@ -721,7 +709,7 @@ impl<'a> TyLoweringContext<'a> {
                     None,
                 );
 
-                let len_self = generics(self.db.upcast(), associated_ty.into()).len_self();
+                let len_self = utils::generics(self.db.upcast(), associated_ty.into()).len_self();
 
                 let substs = Substitution::from_iter(
                     Interner,
@@ -1029,18 +1017,17 @@ impl<'a> TyLoweringContext<'a> {
             | WherePredicate::TypeBound { target, bound } => {
                 let self_ty = match target {
                     WherePredicateTypeTarget::TypeRef(type_ref) => self.lower_ty(type_ref),
-                    WherePredicateTypeTarget::TypeOrConstParam(param_id) => {
-                        let generic_def = self.resolver.generic_def().expect("generics in scope");
-                        let generics = generics(self.db.upcast(), generic_def);
-                        let param_id = hir_def::TypeOrConstParamId {
-                            parent: generic_def,
-                            local_id: *param_id,
-                        };
-                        let placeholder = to_placeholder_idx(self.db, param_id);
+                    &WherePredicateTypeTarget::TypeOrConstParam(local_id) => {
+                        let def = self.resolver.generic_def().expect("generics in scope");
+                        let param_id = hir_def::TypeOrConstParamId { parent: def, local_id };
                         match self.type_param_mode {
-                            ParamLoweringMode::Placeholder => TyKind::Placeholder(placeholder),
+                            ParamLoweringMode::Placeholder => {
+                                TyKind::Placeholder(to_placeholder_idx(self.db, param_id))
+                            }
                             ParamLoweringMode::Variable => {
-                                let idx = generics.param_idx(param_id).expect("matching generics");
+                                let idx = generics(self.db.upcast(), def)
+                                    .param_idx(param_id)
+                                    .expect("matching generics");
                                 TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, idx))
                             }
                         }
@@ -1218,8 +1205,8 @@ impl<'a> TyLoweringContext<'a> {
                                     });
                                 if let Some(target_param_idx) = target_param_idx {
                                     let mut counter = 0;
-                                    for (idx, data) in self.generics().params.type_or_consts.iter()
-                                    {
+                                    let generics = self.generics().expect("generics in scope");
+                                    for (idx, data) in generics.params.type_or_consts.iter() {
                                         // Count the number of `impl Trait` things that appear before
                                         // the target of our `bound`.
                                         // Our counter within `impl_trait_mode` should be that number
@@ -1409,10 +1396,7 @@ impl<'a> TyLoweringContext<'a> {
                         LifetimeData::Placeholder(lt_to_placeholder_idx(self.db, id))
                     }
                     ParamLoweringMode::Variable => {
-                        let generics = generics(
-                            self.db.upcast(),
-                            self.resolver.generic_def().expect("generics in scope"),
-                        );
+                        let generics = self.generics().expect("generics in scope");
                         let idx = match generics.lifetime_idx(id) {
                             None => return error_lifetime(),
                             Some(idx) => idx,
@@ -2258,7 +2242,7 @@ pub(crate) fn const_or_path_to_chalk(
     expected_ty: Ty,
     value: &ConstRef,
     mode: ParamLoweringMode,
-    args: impl FnOnce() -> Generics,
+    args: impl FnOnce() -> Option<Generics>,
     debruijn: DebruijnIndex,
 ) -> Const {
     match value {
@@ -2277,7 +2261,7 @@ pub(crate) fn const_or_path_to_chalk(
             .unwrap_or_else(|| unknown_const(expected_ty))
         }
         &ConstRef::Complex(it) => {
-            let crate_data = &db.crate_graph()[owner.module(db.upcast()).krate()];
+            let crate_data = &db.crate_graph()[resolver.krate()];
             if crate_data.env.get("__ra_is_test_fixture").is_none() && crate_data.origin.is_local()
             {
                 // FIXME: current `InTypeConstId` is very unstable, so we only use it in non local crate
diff --git a/crates/hir-ty/src/utils.rs b/crates/hir-ty/src/utils.rs
index afd4d1f271d..77c5fd054d1 100644
--- a/crates/hir-ty/src/utils.rs
+++ b/crates/hir-ty/src/utils.rs
@@ -262,7 +262,7 @@ impl<'a> ClosureSubst<'a> {
     }
 }
 
-#[derive(Debug)]
+#[derive(Clone, Debug)]
 pub(crate) struct Generics {
     def: GenericDefId,
     pub(crate) params: Interned<GenericParams>,
@@ -274,6 +274,10 @@ impl Generics {
         self.iter().map(|(id, _)| id)
     }
 
+    pub(crate) fn def(&self) -> GenericDefId {
+        self.def
+    }
+
     /// Iterator over types and const params of self, then parent.
     pub(crate) fn iter<'a>(
         &'a self,
@@ -450,6 +454,10 @@ impl Generics {
         self.parent_generics.as_deref()
     }
 
+    pub(crate) fn parent_or_self(&self) -> &Generics {
+        self.parent_generics.as_deref().unwrap_or(self)
+    }
+
     /// Returns a Substitution that replaces each parameter by a bound variable.
     pub(crate) fn bound_vars_subst(
         &self,
diff --git a/crates/limit/Cargo.toml b/crates/limit/Cargo.toml
index c89722cc40d..c1a768833b9 100644
--- a/crates/limit/Cargo.toml
+++ b/crates/limit/Cargo.toml
@@ -10,7 +10,6 @@ rust-version.workspace = true
 
 [features]
 tracking = []
-default = ["tracking"]
 
 [lints]
-workspace = true
\ No newline at end of file
+workspace = true