From cd227f581e0c20d6b9ee81a3982509a9f6b2f67f Mon Sep 17 00:00:00 2001 From: Florian Diebold Date: Sat, 3 Apr 2021 21:50:52 +0200 Subject: Add and start using TraitRef and ProjectionTy builders --- crates/hir_ty/src/infer.rs | 8 +++----- crates/hir_ty/src/infer/path.rs | 16 ++++------------ crates/hir_ty/src/lib.rs | 29 +++++++++++++++++++++++++++++ crates/hir_ty/src/method_resolution.rs | 8 +++----- 4 files changed, 39 insertions(+), 22 deletions(-) (limited to 'crates/hir_ty/src') diff --git a/crates/hir_ty/src/infer.rs b/crates/hir_ty/src/infer.rs index b871594bd..b208d821d 100644 --- a/crates/hir_ty/src/infer.rs +++ b/crates/hir_ty/src/infer.rs @@ -42,7 +42,7 @@ use super::{ }; use crate::{ db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, - to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind, + to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyKind, }; // This lint has a false positive here. See the link below for details. @@ -409,16 +409,14 @@ impl<'a> InferenceContext<'a> { _ => panic!("resolve_associated_type called with non-associated type"), }; let ty = self.table.new_type_var(); - let substs = Substitution::build_for_def(self.db, res_assoc_ty) + let trait_ref = TyBuilder::trait_ref(self.db, trait_) .push(inner_ty) .fill(params.iter().cloned()) .build(); - let trait_ref = - TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() }; let alias_eq = AliasEq { alias: AliasTy::Projection(ProjectionTy { associated_ty_id: to_assoc_type_id(res_assoc_ty), - substitution: substs, + substitution: trait_ref.substitution.clone(), }), ty: ty.clone(), }; diff --git a/crates/hir_ty/src/infer/path.rs b/crates/hir_ty/src/infer/path.rs index 1ba15f737..282dd499f 100644 --- a/crates/hir_ty/src/infer/path.rs +++ b/crates/hir_ty/src/infer/path.rs @@ -10,9 +10,7 @@ use hir_def::{ }; use hir_expand::name::Name; -use crate::{ - method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId, -}; +use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId}; use super::{ExprOrPatId, InferenceContext, TraitRef}; @@ -254,18 +252,12 @@ impl<'a> InferenceContext<'a> { } AssocContainerId::TraitId(trait_) => { // we're picking this method - let trait_substs = Substitution::build_for_def(self.db, trait_) + let trait_ref = TyBuilder::trait_ref(self.db, trait_) .push(ty.clone()) .fill(std::iter::repeat_with(|| self.table.new_type_var())) .build(); - self.push_obligation( - TraitRef { - trait_id: to_chalk_trait_id(trait_), - substitution: trait_substs.clone(), - } - .cast(&Interner), - ); - Some(trait_substs) + self.push_obligation(trait_ref.clone().cast(&Interner)); + Some(trait_ref.substitution) } AssocContainerId::ModuleId(_) => None, }; diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index be6fe5016..e586d73d8 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs @@ -927,6 +927,35 @@ impl TyBuilder { } } +impl TyBuilder { + pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder { + let generics = generics(db.upcast(), trait_id.into()); + let param_count = generics.len(); + TyBuilder::new(trait_id, param_count) + } + + pub fn build(self) -> TraitRef { + let (trait_id, substitution) = self.build_internal(); + TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution } + } +} + +impl TyBuilder { + pub fn assoc_type_projection( + db: &dyn HirDatabase, + type_alias: TypeAliasId, + ) -> TyBuilder { + let generics = generics(db.upcast(), type_alias.into()); + let param_count = generics.len(); + TyBuilder::new(type_alias, param_count) + } + + pub fn build(self) -> ProjectionTy { + let (type_alias, substitution) = self.build_internal(); + ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution } + } +} + impl Ty { pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { match self.kind(&Interner) { diff --git a/crates/hir_ty/src/method_resolution.rs b/crates/hir_ty/src/method_resolution.rs index c093fce20..b9cc081e8 100644 --- a/crates/hir_ty/src/method_resolution.rs +++ b/crates/hir_ty/src/method_resolution.rs @@ -19,10 +19,9 @@ use crate::{ db::HirDatabase, from_foreign_def_id, primitive::{self, FloatTy, IntTy, UintTy}, - to_chalk_trait_id, utils::all_super_traits, AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, - InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind, + InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind, TypeWalk, }; @@ -813,7 +812,7 @@ fn generic_implements_goal( self_ty: Canonical, ) -> Canonical> { let mut kinds = self_ty.binders.interned().to_vec(); - let substs = super::Substitution::build_for_def(db, trait_) + let trait_ref = TyBuilder::trait_ref(db, trait_) .push(self_ty.value) .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) .build(); @@ -822,9 +821,8 @@ fn generic_implements_goal( chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), UniverseIndex::ROOT, )) - .take(substs.len(&Interner) - 1), + .take(trait_ref.substitution.len(&Interner) - 1), ); - let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs }; let obligation = trait_ref.cast(&Interner); Canonical { binders: CanonicalVarKinds::from_iter(&Interner, kinds), -- cgit v1.2.3