aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/lib.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r--crates/hir_ty/src/lib.rs75
1 files changed, 30 insertions, 45 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs
index adfdcaa37..daf379ef8 100644
--- a/crates/hir_ty/src/lib.rs
+++ b/crates/hir_ty/src/lib.rs
@@ -66,6 +66,8 @@ pub type ClosureId = chalk_ir::ClosureId<Interner>;
66pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; 66pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>;
67pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; 67pub type PlaceholderIndex = chalk_ir::PlaceholderIndex;
68 68
69pub type VariableKind = chalk_ir::VariableKind<Interner>;
70pub type VariableKinds = chalk_ir::VariableKinds<Interner>;
69pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; 71pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>;
70 72
71pub type ChalkTraitId = chalk_ir::TraitId<Interner>; 73pub type ChalkTraitId = chalk_ir::TraitId<Interner>;
@@ -118,52 +120,34 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> {
118} 120}
119 121
120impl<T> Binders<T> { 122impl<T> Binders<T> {
121 pub fn new(num_binders: usize, value: T) -> Self {
122 Self { num_binders, value }
123 }
124
125 pub fn wrap_empty(value: T) -> Self 123 pub fn wrap_empty(value: T) -> Self
126 where 124 where
127 T: TypeWalk, 125 T: TypeWalk,
128 { 126 {
129 Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } 127 Binders::empty(&Interner, value.shifted_in_from(DebruijnIndex::ONE))
130 }
131
132 pub fn as_ref(&self) -> Binders<&T> {
133 Binders { num_binders: self.num_binders, value: &self.value }
134 }
135
136 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
137 Binders { num_binders: self.num_binders, value: f(self.value) }
138 }
139
140 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
141 Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
142 }
143
144 pub fn skip_binders(&self) -> &T {
145 &self.value
146 }
147
148 pub fn into_value_and_skipped_binders(self) -> (T, usize) {
149 (self.value, self.num_binders)
150 }
151}
152
153impl<T: Clone> Binders<&T> {
154 pub fn cloned(&self) -> Binders<T> {
155 Binders { num_binders: self.num_binders, value: self.value.clone() }
156 } 128 }
157} 129}
158 130
159impl<T: TypeWalk> Binders<T> { 131impl<T: TypeWalk> Binders<T> {
160 /// Substitutes all variables. 132 /// Substitutes all variables.
161 pub fn subst(self, subst: &Substitution) -> T { 133 pub fn substitute(self, interner: &Interner, subst: &Substitution) -> T {
162 assert_eq!(subst.len(&Interner), self.num_binders); 134 let (value, binders) = self.into_value_and_skipped_binders();
163 self.value.subst_bound_vars(subst) 135 assert_eq!(subst.len(interner), binders.len(interner));
136 value.subst_bound_vars(subst)
164 } 137 }
165} 138}
166 139
140pub fn make_only_type_binders<T>(num_vars: usize, value: T) -> Binders<T> {
141 Binders::new(
142 VariableKinds::from_iter(
143 &Interner,
144 std::iter::repeat(chalk_ir::VariableKind::Ty(chalk_ir::TyVariableKind::General))
145 .take(num_vars),
146 ),
147 value,
148 )
149}
150
167impl TraitRef { 151impl TraitRef {
168 pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { 152 pub fn self_type_parameter(&self, interner: &Interner) -> &Ty {
169 &self.substitution.at(interner, 0).assert_ty_ref(interner) 153 &self.substitution.at(interner, 0).assert_ty_ref(interner)
@@ -225,7 +209,8 @@ impl CallableSig {
225 params_and_return: fn_ptr 209 params_and_return: fn_ptr
226 .substs 210 .substs
227 .clone() 211 .clone()
228 .shift_bound_vars_out(DebruijnIndex::ONE) 212 .shifted_out_to(DebruijnIndex::ONE)
213 .expect("unexpected lifetime vars in fn ptr")
229 .interned() 214 .interned()
230 .iter() 215 .iter()
231 .map(|arg| arg.assert_ty_ref(&Interner).clone()) 216 .map(|arg| arg.assert_ty_ref(&Interner).clone())
@@ -334,12 +319,12 @@ impl Ty {
334 /// If this is a `dyn Trait` type, this returns the `Trait` part. 319 /// If this is a `dyn Trait` type, this returns the `Trait` part.
335 fn dyn_trait_ref(&self) -> Option<&TraitRef> { 320 fn dyn_trait_ref(&self) -> Option<&TraitRef> {
336 match self.kind(&Interner) { 321 match self.kind(&Interner) {
337 TyKind::Dyn(dyn_ty) => { 322 TyKind::Dyn(dyn_ty) => dyn_ty.bounds.skip_binders().interned().get(0).and_then(|b| {
338 dyn_ty.bounds.value.interned().get(0).and_then(|b| match b.skip_binders() { 323 match b.skip_binders() {
339 WhereClause::Implemented(trait_ref) => Some(trait_ref), 324 WhereClause::Implemented(trait_ref) => Some(trait_ref),
340 _ => None, 325 _ => None,
341 }) 326 }
342 } 327 }),
343 _ => None, 328 _ => None,
344 } 329 }
345 } 330 }
@@ -378,7 +363,7 @@ impl Ty {
378 TyKind::FnDef(def, parameters) => { 363 TyKind::FnDef(def, parameters) => {
379 let callable_def = db.lookup_intern_callable_def((*def).into()); 364 let callable_def = db.lookup_intern_callable_def((*def).into());
380 let sig = db.callable_item_signature(callable_def); 365 let sig = db.callable_item_signature(callable_def);
381 Some(sig.subst(&parameters)) 366 Some(sig.substitute(&Interner, &parameters))
382 } 367 }
383 TyKind::Closure(.., substs) => { 368 TyKind::Closure(.., substs) => {
384 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner); 369 let sig_param = substs.at(&Interner, 0).assert_ty_ref(&Interner);
@@ -429,8 +414,8 @@ impl Ty {
429 // This is only used by type walking. 414 // This is only used by type walking.
430 // Parameters will be walked outside, and projection predicate is not used. 415 // Parameters will be walked outside, and projection predicate is not used.
431 // So just provide the Future trait. 416 // So just provide the Future trait.
432 let impl_bound = Binders::new( 417 let impl_bound = Binders::empty(
433 0, 418 &Interner,
434 WhereClause::Implemented(TraitRef { 419 WhereClause::Implemented(TraitRef {
435 trait_id: to_chalk_trait_id(future_trait), 420 trait_id: to_chalk_trait_id(future_trait),
436 substitution: Substitution::empty(&Interner), 421 substitution: Substitution::empty(&Interner),
@@ -452,14 +437,14 @@ impl Ty {
452 let data = (*it) 437 let data = (*it)
453 .as_ref() 438 .as_ref()
454 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone()); 439 .map(|rpit| rpit.impl_traits[idx as usize].bounds.clone());
455 data.subst(&opaque_ty.substitution) 440 data.substitute(&Interner, &opaque_ty.substitution)
456 }) 441 })
457 } 442 }
458 // It always has an parameter for Future::Output type. 443 // It always has an parameter for Future::Output type.
459 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), 444 ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(),
460 }; 445 };
461 446
462 predicates.map(|it| it.value) 447 predicates.map(|it| it.into_value_and_skipped_binders().0)
463 } 448 }
464 TyKind::Placeholder(idx) => { 449 TyKind::Placeholder(idx) => {
465 let id = from_placeholder_idx(db, *idx); 450 let id = from_placeholder_idx(db, *idx);
@@ -471,7 +456,7 @@ impl Ty {
471 let predicates = db 456 let predicates = db
472 .generic_predicates(id.parent) 457 .generic_predicates(id.parent)
473 .into_iter() 458 .into_iter()
474 .map(|pred| pred.clone().subst(&substs)) 459 .map(|pred| pred.clone().substitute(&Interner, &substs))
475 .filter(|wc| match &wc.skip_binders() { 460 .filter(|wc| match &wc.skip_binders() {
476 WhereClause::Implemented(tr) => { 461 WhereClause::Implemented(tr) => {
477 tr.self_type_parameter(&Interner) == self 462 tr.self_type_parameter(&Interner) == self