aboutsummaryrefslogtreecommitdiff
path: root/crates
diff options
context:
space:
mode:
authorFlorian Diebold <[email protected]>2021-04-03 20:50:52 +0100
committerFlorian Diebold <[email protected]>2021-04-04 12:16:38 +0100
commitcd227f581e0c20d6b9ee81a3982509a9f6b2f67f (patch)
tree2e5c7b11b179b1a318b4bc527c91cbf3b81239f7 /crates
parent2ead65190ecaf1096a998d88d4aab8505ce88afa (diff)
Add and start using TraitRef and ProjectionTy builders
Diffstat (limited to 'crates')
-rw-r--r--crates/hir/src/lib.rs24
-rw-r--r--crates/hir_ty/src/infer.rs8
-rw-r--r--crates/hir_ty/src/infer/path.rs16
-rw-r--r--crates/hir_ty/src/lib.rs29
-rw-r--r--crates/hir_ty/src/method_resolution.rs8
-rw-r--r--crates/ide/src/inlay_hints.rs2
6 files changed, 48 insertions, 39 deletions
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::{
55 autoderef, could_unify, 55 autoderef, could_unify,
56 method_resolution::{self, TyFingerprint}, 56 method_resolution::{self, TyFingerprint},
57 primitive::UintTy, 57 primitive::UintTy,
58 to_assoc_type_id,
59 traits::{FnTrait, Solution, SolutionVariables}, 58 traits::{FnTrait, Solution, SolutionVariables},
60 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast, 59 AliasEq, AliasTy, BoundVar, CallableDefId, CallableSig, Canonical, CanonicalVarKinds, Cast,
61 DebruijnIndex, InEnvironment, Interner, ProjectionTy, QuantifiedWhereClause, Scalar, 60 DebruijnIndex, InEnvironment, Interner, QuantifiedWhereClause, Scalar, Substitution,
62 Substitution, TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause, 61 TraitEnvironment, Ty, TyBuilder, TyDefId, TyKind, TyVariableKind, WhereClause,
63}; 62};
64use itertools::Itertools; 63use itertools::Itertools;
65use rustc_hash::FxHashSet; 64use rustc_hash::FxHashSet;
@@ -1785,13 +1784,10 @@ impl Type {
1785 } 1784 }
1786 1785
1787 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool { 1786 pub fn impls_trait(&self, db: &dyn HirDatabase, trait_: Trait, args: &[Type]) -> bool {
1788 let trait_ref = hir_ty::TraitRef { 1787 let trait_ref = TyBuilder::trait_ref(db, trait_.id)
1789 trait_id: hir_ty::to_chalk_trait_id(trait_.id), 1788 .push(self.ty.clone())
1790 substitution: Substitution::build_for_def(db, trait_.id) 1789 .fill(args.iter().map(|t| t.ty.clone()))
1791 .push(self.ty.clone()) 1790 .build();
1792 .fill(args.iter().map(|t| t.ty.clone()))
1793 .build(),
1794 };
1795 1791
1796 let goal = Canonical { 1792 let goal = Canonical {
1797 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)), 1793 value: hir_ty::InEnvironment::new(self.env.env.clone(), trait_ref.cast(&Interner)),
@@ -1804,11 +1800,10 @@ impl Type {
1804 pub fn normalize_trait_assoc_type( 1800 pub fn normalize_trait_assoc_type(
1805 &self, 1801 &self,
1806 db: &dyn HirDatabase, 1802 db: &dyn HirDatabase,
1807 trait_: Trait,
1808 args: &[Type], 1803 args: &[Type],
1809 alias: TypeAlias, 1804 alias: TypeAlias,
1810 ) -> Option<Type> { 1805 ) -> Option<Type> {
1811 let subst = Substitution::build_for_def(db, trait_.id) 1806 let projection = TyBuilder::assoc_type_projection(db, alias.id)
1812 .push(self.ty.clone()) 1807 .push(self.ty.clone())
1813 .fill(args.iter().map(|t| t.ty.clone())) 1808 .fill(args.iter().map(|t| t.ty.clone()))
1814 .build(); 1809 .build();
@@ -1816,10 +1811,7 @@ impl Type {
1816 InEnvironment::new( 1811 InEnvironment::new(
1817 self.env.env.clone(), 1812 self.env.env.clone(),
1818 AliasEq { 1813 AliasEq {
1819 alias: AliasTy::Projection(ProjectionTy { 1814 alias: AliasTy::Projection(projection),
1820 associated_ty_id: to_assoc_type_id(alias.id),
1821 substitution: subst,
1822 }),
1823 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0)) 1815 ty: TyKind::BoundVar(BoundVar::new(DebruijnIndex::INNERMOST, 0))
1824 .intern(&Interner), 1816 .intern(&Interner),
1825 } 1817 }
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::{
42}; 42};
43use crate::{ 43use crate::{
44 db::HirDatabase, infer::diagnostics::InferenceDiagnostic, lower::ImplTraitLoweringMode, 44 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,
46}; 46};
47 47
48// This lint has a false positive here. See the link below for details. 48// This lint has a false positive here. See the link below for details.
@@ -409,16 +409,14 @@ impl<'a> InferenceContext<'a> {
409 _ => panic!("resolve_associated_type called with non-associated type"), 409 _ => panic!("resolve_associated_type called with non-associated type"),
410 }; 410 };
411 let ty = self.table.new_type_var(); 411 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_)
413 .push(inner_ty) 413 .push(inner_ty)
414 .fill(params.iter().cloned()) 414 .fill(params.iter().cloned())
415 .build(); 415 .build();
416 let trait_ref =
417 TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs.clone() };
418 let alias_eq = AliasEq { 416 let alias_eq = AliasEq {
419 alias: AliasTy::Projection(ProjectionTy { 417 alias: AliasTy::Projection(ProjectionTy {
420 associated_ty_id: to_assoc_type_id(res_assoc_ty), 418 associated_ty_id: to_assoc_type_id(res_assoc_ty),
421 substitution: substs, 419 substitution: trait_ref.substitution.clone(),
422 }), 420 }),
423 ty: ty.clone(), 421 ty: ty.clone(),
424 }; 422 };
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::{
10}; 10};
11use hir_expand::name::Name; 11use hir_expand::name::Name;
12 12
13use crate::{ 13use crate::{method_resolution, Interner, Substitution, Ty, TyBuilder, TyKind, ValueTyDefId};
14 method_resolution, to_chalk_trait_id, Interner, Substitution, Ty, TyKind, ValueTyDefId,
15};
16 14
17use super::{ExprOrPatId, InferenceContext, TraitRef}; 15use super::{ExprOrPatId, InferenceContext, TraitRef};
18 16
@@ -254,18 +252,12 @@ impl<'a> InferenceContext<'a> {
254 } 252 }
255 AssocContainerId::TraitId(trait_) => { 253 AssocContainerId::TraitId(trait_) => {
256 // we're picking this method 254 // 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_)
258 .push(ty.clone()) 256 .push(ty.clone())
259 .fill(std::iter::repeat_with(|| self.table.new_type_var())) 257 .fill(std::iter::repeat_with(|| self.table.new_type_var()))
260 .build(); 258 .build();
261 self.push_obligation( 259 self.push_obligation(trait_ref.clone().cast(&Interner));
262 TraitRef { 260 Some(trait_ref.substitution)
263 trait_id: to_chalk_trait_id(trait_),
264 substitution: trait_substs.clone(),
265 }
266 .cast(&Interner),
267 );
268 Some(trait_substs)
269 } 261 }
270 AssocContainerId::ModuleId(_) => None, 262 AssocContainerId::ModuleId(_) => None,
271 }; 263 };
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<hir_def::AdtId> {
927 } 927 }
928} 928}
929 929
930impl 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
943impl 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
930impl Ty { 959impl Ty {
931 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> { 960 pub fn as_reference(&self) -> Option<(&Ty, Mutability)> {
932 match self.kind(&Interner) { 961 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::{
19 db::HirDatabase, 19 db::HirDatabase,
20 from_foreign_def_id, 20 from_foreign_def_id,
21 primitive::{self, FloatTy, IntTy, UintTy}, 21 primitive::{self, FloatTy, IntTy, UintTy},
22 to_chalk_trait_id,
23 utils::all_super_traits, 22 utils::all_super_traits,
24 AdtId, Canonical, CanonicalVarKinds, DebruijnIndex, FnPointer, FnSig, ForeignDefId, 23 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,
26 TypeWalk, 25 TypeWalk,
27}; 26};
28 27
@@ -813,7 +812,7 @@ fn generic_implements_goal(
813 self_ty: Canonical<Ty>, 812 self_ty: Canonical<Ty>,
814) -> Canonical<InEnvironment<super::DomainGoal>> { 813) -> Canonical<InEnvironment<super::DomainGoal>> {
815 let mut kinds = self_ty.binders.interned().to_vec(); 814 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_)
817 .push(self_ty.value) 816 .push(self_ty.value)
818 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len()) 817 .fill_with_bound_vars(DebruijnIndex::INNERMOST, kinds.len())
819 .build(); 818 .build();
@@ -822,9 +821,8 @@ fn generic_implements_goal(
822 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General), 821 chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General),
823 UniverseIndex::ROOT, 822 UniverseIndex::ROOT,
824 )) 823 ))
825 .take(substs.len(&Interner) - 1), 824 .take(trait_ref.substitution.len(&Interner) - 1),
826 ); 825 );
827 let trait_ref = TraitRef { trait_id: to_chalk_trait_id(trait_), substitution: substs };
828 let obligation = trait_ref.cast(&Interner); 826 let obligation = trait_ref.cast(&Interner);
829 Canonical { 827 Canonical {
830 binders: CanonicalVarKinds::from_iter(&Interner, kinds), 828 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(
234 hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias), 234 hir::AssocItem::TypeAlias(alias) if alias.name(db) == known::Item => Some(alias),
235 _ => None, 235 _ => None,
236 })?; 236 })?;
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) {
238 const LABEL_START: &str = "impl Iterator<Item = "; 238 const LABEL_START: &str = "impl Iterator<Item = ";
239 const LABEL_END: &str = ">"; 239 const LABEL_END: &str = ">";
240 240