From e480d81988fc0c0e4f80f1c54058b95b9aaf1ebf Mon Sep 17 00:00:00 2001
From: Florian Diebold <flodiebold@gmail.com>
Date: Thu, 1 Apr 2021 21:04:02 +0200
Subject: Introduce `GenericArg` like in Chalk

Plus some more adaptations to Substitution.

Lots of `assert_ty_ref` that we should revisit when introducing
lifetime/const parameters.
---
 crates/hir_ty/src/traits/chalk.rs         | 10 ++++----
 crates/hir_ty/src/traits/chalk/mapping.rs | 39 +++++++++++++++++++++----------
 2 files changed, 32 insertions(+), 17 deletions(-)

(limited to 'crates/hir_ty/src/traits')

diff --git a/crates/hir_ty/src/traits/chalk.rs b/crates/hir_ty/src/traits/chalk.rs
index 011bef6f6..cf7ed1e11 100644
--- a/crates/hir_ty/src/traits/chalk.rs
+++ b/crates/hir_ty/src/traits/chalk.rs
@@ -3,7 +3,7 @@ use std::sync::Arc;
 
 use log::debug;
 
-use chalk_ir::{fold::shift::Shift, CanonicalVarKinds, GenericArg};
+use chalk_ir::{fold::shift::Shift, CanonicalVarKinds};
 use chalk_solve::rust_ir::{self, OpaqueTyDatumBound, WellKnownTrait};
 
 use base_db::{salsa::InternKey, CrateId};
@@ -80,7 +80,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
     fn impls_for_trait(
         &self,
         trait_id: TraitId,
-        parameters: &[GenericArg<Interner>],
+        parameters: &[chalk_ir::GenericArg<Interner>],
         binders: &CanonicalVarKinds<Interner>,
     ) -> Vec<ImplId> {
         debug!("impls_for_trait {:?}", trait_id);
@@ -308,7 +308,7 @@ impl<'a> chalk_solve::RustIrDatabase<Interner> for ChalkContext<'a> {
         _closure_id: chalk_ir::ClosureId<Interner>,
         _substs: &chalk_ir::Substitution<Interner>,
     ) -> chalk_ir::Substitution<Interner> {
-        Substitution::empty().to_chalk(self.db)
+        Substitution::empty(&Interner).to_chalk(self.db)
     }
 
     fn trait_name(&self, trait_id: chalk_ir::TraitId<Interner>) -> String {
@@ -439,7 +439,7 @@ pub(crate) fn trait_datum_query(
         lang_attr(db.upcast(), trait_).and_then(|name| well_known_trait_from_lang_attr(&name));
     let trait_datum = TraitDatum {
         id: trait_id,
-        binders: make_binders(trait_datum_bound, bound_vars.len()),
+        binders: make_binders(trait_datum_bound, bound_vars.len(&Interner)),
         flags,
         associated_ty_ids,
         well_known,
@@ -577,7 +577,7 @@ fn impl_def_datum(
         .collect();
     debug!("impl_datum: {:?}", impl_datum_bound);
     let impl_datum = ImplDatum {
-        binders: make_binders(impl_datum_bound, bound_vars.len()),
+        binders: make_binders(impl_datum_bound, bound_vars.len(&Interner)),
         impl_type,
         polarity,
         associated_ty_value_ids,
diff --git a/crates/hir_ty/src/traits/chalk/mapping.rs b/crates/hir_ty/src/traits/chalk/mapping.rs
index aef6b8a15..452b357e8 100644
--- a/crates/hir_ty/src/traits/chalk/mapping.rs
+++ b/crates/hir_ty/src/traits/chalk/mapping.rs
@@ -13,7 +13,7 @@ use crate::{
     db::HirDatabase,
     primitive::UintTy,
     traits::{Canonical, DomainGoal},
-    AliasTy, CallableDefId, FnPointer, InEnvironment, OpaqueTy, ProjectionTy,
+    AliasTy, CallableDefId, FnPointer, GenericArg, InEnvironment, OpaqueTy, ProjectionTy,
     QuantifiedWhereClause, Scalar, Substitution, TraitRef, Ty, TypeWalk, WhereClause,
 };
 
@@ -137,7 +137,7 @@ impl ToChalk for Ty {
                     db,
                     substitution.0.shifted_out(&Interner).expect("fn ptr should have no binders"),
                 );
-                TyKind::Function(FnPointer { num_args: (substs.len() - 1), sig, substs })
+                TyKind::Function(FnPointer { num_args: (substs.len(&Interner) - 1), sig, substs })
             }
             chalk_ir::TyKind::BoundVar(idx) => TyKind::BoundVar(idx),
             chalk_ir::TyKind::InferenceVar(_iv, _kind) => TyKind::Unknown,
@@ -216,24 +216,39 @@ fn array_to_chalk(db: &dyn HirDatabase, ty: Ty) -> chalk_ir::Ty<Interner> {
     chalk_ir::TyKind::Array(arg, const_).intern(&Interner)
 }
 
+impl ToChalk for GenericArg {
+    type Chalk = chalk_ir::GenericArg<Interner>;
+
+    fn to_chalk(self, db: &dyn HirDatabase) -> Self::Chalk {
+        match self.interned {
+            crate::GenericArgData::Ty(ty) => ty.to_chalk(db).cast(&Interner),
+        }
+    }
+
+    fn from_chalk(db: &dyn HirDatabase, chalk: Self::Chalk) -> Self {
+        match chalk.interned() {
+            chalk_ir::GenericArgData::Ty(ty) => Ty::from_chalk(db, ty.clone()).cast(&Interner),
+            chalk_ir::GenericArgData::Lifetime(_) => unimplemented!(),
+            chalk_ir::GenericArgData::Const(_) => unimplemented!(),
+        }
+    }
+}
+
 impl ToChalk for Substitution {
     type Chalk = chalk_ir::Substitution<Interner>;
 
     fn to_chalk(self, db: &dyn HirDatabase) -> chalk_ir::Substitution<Interner> {
-        chalk_ir::Substitution::from_iter(&Interner, self.iter().map(|ty| ty.clone().to_chalk(db)))
+        chalk_ir::Substitution::from_iter(
+            &Interner,
+            self.iter(&Interner).map(|ty| ty.clone().to_chalk(db)),
+        )
     }
 
     fn from_chalk(
         db: &dyn HirDatabase,
         parameters: chalk_ir::Substitution<Interner>,
     ) -> Substitution {
-        let tys = parameters
-            .iter(&Interner)
-            .map(|p| match p.ty(&Interner) {
-                Some(ty) => from_chalk(db, ty.clone()),
-                None => unimplemented!(),
-            })
-            .collect();
+        let tys = parameters.iter(&Interner).map(|p| from_chalk(db, p.clone())).collect();
         Substitution(tys)
     }
 }
@@ -531,7 +546,7 @@ pub(super) fn generic_predicate_to_inline_bound(
                 // have the expected self type
                 return None;
             }
-            let args_no_self = trait_ref.substitution[1..]
+            let args_no_self = trait_ref.substitution.interned(&Interner)[1..]
                 .iter()
                 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
                 .collect();
@@ -543,7 +558,7 @@ pub(super) fn generic_predicate_to_inline_bound(
                 return None;
             }
             let trait_ = projection_ty.trait_(db);
-            let args_no_self = projection_ty.substitution[1..]
+            let args_no_self = projection_ty.substitution.interned(&Interner)[1..]
                 .iter()
                 .map(|ty| ty.clone().to_chalk(db).cast(&Interner))
                 .collect();
-- 
cgit v1.2.3