]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/method_resolution.rs
Add const generics
[rust.git] / crates / hir_ty / src / method_resolution.rs
index 44ece57a8e0e74142df94770fd828a1bfa6fd7bf..06c834fbc89e1702cea99de5b229a2f0bbe8932c 100644 (file)
@@ -6,7 +6,7 @@
 
 use arrayvec::ArrayVec;
 use base_db::{CrateId, Edition};
-use chalk_ir::{cast::Cast, Mutability, UniverseIndex};
+use chalk_ir::{cast::Cast, fold::Fold, interner::HasInterner, Mutability, UniverseIndex};
 use hir_def::{
     item_scope::ItemScope, lang_item::LangItemTarget, nameres::DefMap, AssocItemId, BlockId,
     ConstId, FunctionId, GenericDefId, HasModule, ImplId, ItemContainerId, Lookup, ModuleDefId,
@@ -25,8 +25,9 @@
     primitive::{self, FloatTy, IntTy, UintTy},
     static_lifetime,
     utils::all_super_traits,
-    AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, InEnvironment, Interner,
-    Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder, TyExt, TyKind,
+    AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, ForeignDefId, GenericArgData,
+    InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRefExt, Ty, TyBuilder,
+    TyExt, TyKind,
 };
 
 /// This is used as a key for indexing impls.
@@ -278,7 +279,7 @@ pub(crate) fn inherent_impls_in_crate_query(db: &dyn HirDatabase, krate: CrateId
         impls.collect_def_map(db, &crate_def_map);
         impls.shrink_to_fit();
 
-        return Arc::new(impls);
+        Arc::new(impls)
     }
 
     pub(crate) fn inherent_impls_in_block_query(
@@ -291,7 +292,7 @@ pub(crate) fn inherent_impls_in_block_query(
             impls.shrink_to_fit();
             return Some(Arc::new(impls));
         }
-        return None;
+        None
     }
 
     fn shrink_to_fit(&mut self) {
@@ -663,7 +664,7 @@ pub fn iterate_method_candidates_dyn(
             iterate_method_candidates_for_self_ty(
                 ty,
                 db,
-                env.clone(),
+                env,
                 traits_in_scope,
                 visible_from_module,
                 name,
@@ -693,7 +694,7 @@ fn iterate_method_candidates_with_autoref(
     iterate_method_candidates_by_receiver(
         receiver_ty,
         first_adjustment.clone(),
-        &rest,
+        rest,
         db,
         env.clone(),
         traits_in_scope,
@@ -731,7 +732,7 @@ fn iterate_method_candidates_with_autoref(
         first_adjustment.with_autoref(Mutability::Mut),
         deref_chain,
         db,
-        env.clone(),
+        env,
         traits_in_scope,
         visible_from_module,
         name,
@@ -973,7 +974,7 @@ fn impls_for_self_ty(
                 // already happens in `is_valid_candidate` above; if not, we
                 // check it here
                 if receiver_ty.is_none()
-                    && inherent_impl_substs(db, env.clone(), impl_def, &self_ty).is_none()
+                    && inherent_impl_substs(db, env.clone(), impl_def, self_ty).is_none()
                 {
                     cov_mark::hit!(impl_self_type_match_without_receiver);
                     continue;
@@ -1087,13 +1088,14 @@ pub(crate) fn inherent_impl_substs(
         .build();
     let self_ty_with_vars = db.impl_self_ty(impl_id).substitute(Interner, &vars);
     let mut kinds = self_ty.binders.interned().to_vec();
-    kinds.extend(
-        iter::repeat(chalk_ir::WithKind::new(
-            chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
-            UniverseIndex::ROOT,
-        ))
-        .take(vars.len(Interner)),
-    );
+    kinds.extend(vars.iter(Interner).map(|x| {
+        let kind = match x.data(Interner) {
+            GenericArgData::Ty(_) => chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
+            GenericArgData::Const(c) => chalk_ir::VariableKind::Const(c.data(Interner).ty.clone()),
+            GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
+        };
+        chalk_ir::WithKind::new(kind, UniverseIndex::ROOT)
+    }));
     let tys = Canonical {
         binders: CanonicalVarKinds::from_iter(Interner, kinds),
         value: (self_ty_with_vars, self_ty.value.clone()),
@@ -1105,20 +1107,33 @@ pub(crate) fn inherent_impl_substs(
     // Unknown, and in that case we want the result to contain Unknown in those
     // places again.
     let suffix =
-        Substitution::from_iter(Interner, substs.iter(Interner).cloned().skip(self_ty_vars));
+        Substitution::from_iter(Interner, substs.iter(Interner).skip(self_ty_vars).cloned());
     Some(fallback_bound_vars(suffix, self_ty_vars))
 }
 
 /// This replaces any 'free' Bound vars in `s` (i.e. those with indices past
 /// num_vars_to_keep) by `TyKind::Unknown`.
-fn fallback_bound_vars(s: Substitution, num_vars_to_keep: usize) -> Substitution {
-    crate::fold_free_vars(s, |bound, binders| {
-        if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
-            TyKind::Error.intern(Interner)
-        } else {
-            bound.shifted_in_from(binders).to_ty(Interner)
-        }
-    })
+pub(crate) fn fallback_bound_vars<T: Fold<Interner> + HasInterner<Interner = Interner>>(
+    s: T,
+    num_vars_to_keep: usize,
+) -> T::Result {
+    crate::fold_free_vars(
+        s,
+        |bound, binders| {
+            if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
+                TyKind::Error.intern(Interner)
+            } else {
+                bound.shifted_in_from(binders).to_ty(Interner)
+            }
+        },
+        |ty, bound, binders| {
+            if bound.index >= num_vars_to_keep && bound.debruijn == DebruijnIndex::INNERMOST {
+                consteval::usize_const(None)
+            } else {
+                bound.shifted_in_from(binders).to_const(Interner, ty)
+            }
+        },
+    )
 }
 
 fn transform_receiver_ty(
@@ -1152,7 +1167,7 @@ pub fn implements_trait(
     env: Arc<TraitEnvironment>,
     trait_: TraitId,
 ) -> bool {
-    let goal = generic_implements_goal(db, env.clone(), trait_, &ty);
+    let goal = generic_implements_goal(db, env.clone(), trait_, ty);
     let solution = db.trait_solve(env.krate, goal.cast(Interner));
 
     solution.is_some()
@@ -1164,7 +1179,7 @@ pub fn implements_trait_unique(
     env: Arc<TraitEnvironment>,
     trait_: TraitId,
 ) -> bool {
-    let goal = generic_implements_goal(db, env.clone(), trait_, &ty);
+    let goal = generic_implements_goal(db, env.clone(), trait_, ty);
     let solution = db.trait_solve(env.krate, goal.cast(Interner));
 
     matches!(solution, Some(crate::Solution::Unique(_)))
@@ -1183,13 +1198,18 @@ fn generic_implements_goal(
         .push(self_ty.value.clone())
         .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
         .build();
-    kinds.extend(
-        iter::repeat(chalk_ir::WithKind::new(
-            chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
-            UniverseIndex::ROOT,
-        ))
-        .take(trait_ref.substitution.len(Interner) - 1),
-    );
+    kinds.extend(trait_ref.substitution.iter(Interner).skip(1).map(|x| {
+        let vk = match x.data(Interner) {
+            chalk_ir::GenericArgData::Ty(_) => {
+                chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General)
+            }
+            chalk_ir::GenericArgData::Lifetime(_) => chalk_ir::VariableKind::Lifetime,
+            chalk_ir::GenericArgData::Const(c) => {
+                chalk_ir::VariableKind::Const(c.data(Interner).ty.clone())
+            }
+        };
+        chalk_ir::WithKind::new(vk, UniverseIndex::ROOT)
+    }));
     let obligation = trait_ref.cast(Interner);
     Canonical {
         binders: CanonicalVarKinds::from_iter(Interner, kinds),