Skip to content

Commit cd227f5

Browse files
committed
Add and start using TraitRef and ProjectionTy builders
1 parent 2ead651 commit cd227f5

File tree

6 files changed

+48
-39
lines changed

6 files changed

+48
-39
lines changed

crates/hir/src/lib.rs

Lines changed: 8 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -55,11 +55,10 @@ use hir_ty::{
5555
autoderef, could_unify,
5656
method_resolution::{self, TyFingerprint},
5757
primitive::UintTy,
58-
to_assoc_type_id,
5958
traits::{FnTrait, Solution, SolutionVariables},
6059
AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
61-
DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar,
62-
Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause,
60+
DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Substitution,
61+
TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause,
6362
};
6463
use itertools::Itertools;
6564
use rustc_hash::FxHashSet;
@@ -1785,13 +1784,10 @@ impl Type {
17851784
}
17861785

17871786
pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1788-
let trait_ref = hir_ty::TraitRef {
1789-
trait_id: hir_ty::to_chalk_trait_id(trait_.id),
1790-
substitution: Substitution::build_for_def(db, trait_.id)
1791-
.push(self.ty.clone())
1792-
.fill(args.iter().map(|t| t.ty.clone()))
1793-
.build(),
1794-
};
1787+
let trait_ref = TyBuilder::trait_ref(db, trait_.id)
1788+
.push(self.ty.clone())
1789+
.fill(args.iter().map(|t| t.ty.clone()))
1790+
.build();
17951791

17961792
let goal = Canonical {
17971793
value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
@@ -1804,22 +1800,18 @@ impl Type {
18041800
pub fn normalize_trait_assoc_type(
18051801
&self,
18061802
db: &dyn HirDatabase,
1807-
trait_: Trait,
18081803
args: &[Type],
18091804
alias: TypeAlias,
18101805
) -> Option<Type> {
1811-
let subst = Substitution::build_for_def(db, trait_.id)
1806+
let projection = TyBuilder::assoc_type_projection(db, alias.id)
18121807
.push(self.ty.clone())
18131808
.fill(args.iter().map(|t| t.ty.clone()))
18141809
.build();
18151810
let goal = Canonical::new(
18161811
InEnvironment::new(
18171812
self.env.env.clone(),
18181813
AliasEq {
1819-
alias: AliasTy::Projection(ProjectionTy {
1820-
associated_ty_id: to_assoc_type_id(alias.id),
1821-
substitution: subst,
1822-
}),
1814+
alias: AliasTy::Projection(projection),
18231815
ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
18241816
.intern(&Interner),
18251817
}

crates/hir_ty/src/infer.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ use super::{
4242
};
4343
use crate::{
4444
db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode,
45-
to_assoc_type_id, to_chalk_trait_id, AliasEq, AliasTy, Interner, TyKind,
45+
to_assoc_type_id, AliasEq, AliasTy, Interner, TyBuilder, TyKind,
4646
};
4747

4848
// This lint has a false positive here. See the link below for details.
@@ -409,16 +409,14 @@ impl<'a> InferenceContext<'a> {
409409
_ => panic!("resolve_associated_type called with non-associated type"),
410410
};
411411
let ty = self.table.new_type_var();
412-
let substs = Substitution::build_for_def(self.db, res_assoc_ty)
412+
let trait_ref = TyBuilder::trait_ref(self.db, trait_)
413413
.push(inner_ty)
414414
.fill(params.iter().cloned())
415415
.build();
416-
let trait_ref =
417-
TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
418416
let alias_eq = AliasEq {
419417
alias: AliasTy::Projection(ProjectionTy {
420418
associated_ty_id: to_assoc_type_id(res_assoc_ty),
421-
substitution: substs,
419+
substitution: trait_ref.substitution.clone(),
422420
}),
423421
ty: ty.clone(),
424422
};

crates/hir_ty/src/infer/path.rs

Lines changed: 4 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,7 @@ use hir_def::{
1010
};
1111
use hir_expand::name::Name;
1212

13-
use crate::{
14-
method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
15-
};
13+
use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId};
1614

1715
use super::{ExprOrPatId, InferenceContext, TraitRef};
1816

@@ -254,18 +252,12 @@ impl<'a> InferenceContext<'a> {
254252
}
255253
AssocContainerId::TraitId(trait_) => {
256254
// we're picking this method
257-
let trait_substs = Substitution::build_for_def(self.db, trait_)
255+
let trait_ref = TyBuilder::trait_ref(self.db, trait_)
258256
.push(ty.clone())
259257
.fill(std::iter::repeat_with(|| self.table.new_type_var()))
260258
.build();
261-
self.push_obligation(
262-
TraitRef {
263-
trait_id: to_chalk_trait_id(trait_),
264-
substitution: trait_substs.clone(),
265-
}
266-
.cast(&Interner),
267-
);
268-
Some(trait_substs)
259+
self.push_obligation(trait_ref.clone().cast(&Interner));
260+
Some(trait_ref.substitution)
269261
}
270262
AssocContainerId::ModuleId(_) => None,
271263
};

crates/hir_ty/src/lib.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,35 @@ impl TyBuilder<hir_def::AdtId> {
927927
}
928928
}
929929

930+
impl TyBuilder<TraitId> {
931+
pub fn trait_ref(db: &dyn HirDatabase, trait_id: TraitId) -> TyBuilder<TraitId> {
932+
let generics = generics(db.upcast(), trait_id.into());
933+
let param_count = generics.len();
934+
TyBuilder::new(trait_id, param_count)
935+
}
936+
937+
pub fn build(self) -> TraitRef {
938+
let (trait_id, substitution) = self.build_internal();
939+
TraitRef { trait_id: to_chalk_trait_id(trait_id), substitution }
940+
}
941+
}
942+
943+
impl TyBuilder<TypeAliasId> {
944+
pub fn assoc_type_projection(
945+
db: &dyn HirDatabase,
946+
type_alias: TypeAliasId,
947+
) -> TyBuilder<TypeAliasId> {
948+
let generics = generics(db.upcast(), type_alias.into());
949+
let param_count = generics.len();
950+
TyBuilder::new(type_alias, param_count)
951+
}
952+
953+
pub fn build(self) -> ProjectionTy {
954+
let (type_alias, substitution) = self.build_internal();
955+
ProjectionTy { associated_ty_id: to_assoc_type_id(type_alias), substitution }
956+
}
957+
}
958+
930959
impl Ty {
931960
pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
932961
match self.kind(&Interner) {

crates/hir_ty/src/method_resolution.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,9 @@ use crate::{
1919
db::HirDatabase,
2020
from_foreign_def_id,
2121
primitive::{self, FloatTy, IntTy, UintTy},
22-
to_chalk_trait_id,
2322
utils::all_super_traits,
2423
AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId,
25-
InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, TraitRef, Ty, TyKind,
24+
InEnvironment, Interner, Scalar, Substitution, TraitEnvironment, Ty, TyBuilder, TyKind,
2625
TypeWalk,
2726
};
2827

@@ -813,7 +812,7 @@ fn generic_implements_goal(
813812
self_ty: Canonical<Ty>,
814813
) -> Canonical<InEnvironment<super::DomainGoal>> {
815814
let mut kinds = self_ty.binders.interned().to_vec();
816-
let substs = super::Substitution::build_for_def(db, trait_)
815+
let trait_ref = TyBuilder::trait_ref(db, trait_)
817816
.push(self_ty.value)
818817
.fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
819818
.build();
@@ -822,9 +821,8 @@ fn generic_implements_goal(
822821
chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
823822
UniverseIndex::ROOT,
824823
))
825-
.take(substs.len(&Interner) - 1),
824+
.take(trait_ref.substitution.len(&Interner) - 1),
826825
);
827-
let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
828826
let obligation = trait_ref.cast(&Interner);
829827
Canonical {
830828
binders: CanonicalVarKinds::from_iter(&Interner, kinds),

crates/ide/src/inlay_hints.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -234,7 +234,7 @@ fn hint_iterator(
234234
hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias),
235235
_ => None,
236236
})?;
237-
if let Some(ty) = ty.normalize_trait_assoc_type(db, iter_trait, &[], assoc_type_item) {
237+
if let Some(ty) = ty.normalize_trait_assoc_type(db, &[], assoc_type_item) {
238238
const LABEL_START: &str = "impl Iterator<Item = ";
239239
const LABEL_END: &str = ">";
240240

0 commit comments

Comments
 (0)