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/src/lib.rs | 24 ++++++++---------------- 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 +++----- crates/ide/src/inlay_hints.rs | 2 +- 6 files changed, 48 insertions(+), 39 deletions(-) (limited to 'crates') diff --git a/crates/hir/src/lib.rs b/crates/hir/src/lib.rs index 682d49a21..15f46f720 100644 --- a/crates/hir/src/lib.rs +++ b/crates/hir/src/lib.rs @@ -55,11 +55,10 @@ use hir_ty::{ autoderef, could_unify, method_resolution::{self, TyFingerprint}, primitive::UintTy, - to_assoc_type_id, traits::{FnTrait, Solution, SolutionVariables}, AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, - DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, - Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause, + DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Substitution, + TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause, }; use itertools::Itertools; use rustc_hash::FxHashSet; @@ -1785,13 +1784,10 @@ impl Type { } pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { - let trait_ref = hir_ty::TraitRef { - trait_id: hir_ty::to_chalk_trait_id(trait_.id), - substitution: Substitution::build_for_def(db, trait_.id) - .push(self.ty.clone()) - .fill(args.iter().map(|t| t.ty.clone())) - .build(), - }; + let trait_ref = TyBuilder::trait_ref(db, trait_.id) + .push(self.ty.clone()) + .fill(args.iter().map(|t| t.ty.clone())) + .build(); let goal = Canonical { value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), @@ -1804,11 +1800,10 @@ impl Type { pub fn normalize_trait_assoc_type( &self, db: &dyn HirDatabase, - trait_: Trait, args: &[Type], alias: TypeAlias, ) -> Option { - let subst = Substitution::build_for_def(db, trait_.id) + let projection = TyBuilder::assoc_type_projection(db, alias.id) .push(self.ty.clone()) .fill(args.iter().map(|t| t.ty.clone())) .build(); @@ -1816,10 +1811,7 @@ impl Type { InEnvironment::new( self.env.env.clone(), AliasEq { - alias: AliasTy::Projection(ProjectionTy { - associated_ty_id: to_assoc_type_id(alias.id), - substitution: subst, - }), + alias: AliasTy::Projection(projection), ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) .intern(&Interner), } 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), diff --git a/crates/ide/src/inlay_hints.rs b/crates/ide/src/inlay_hints.rs index f73edf8b6..d5ef054d8 100644 --- a/crates/ide/src/inlay_hints.rs +++ b/crates/ide/src/inlay_hints.rs @@ -234,7 +234,7 @@ fn hint_iterator( hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias), _ => None, })?; - if let Some(ty) = ty.normalize_trait_assoc_type(db, iter_trait, &[], assoc_type_item) { + if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) { const LABEL_START: &str = "impl Iterator