diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 89 |
1 files changed, 38 insertions, 51 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index d1513df1f..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>; | |||
66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; | 66 | pub type OpaqueTyId = chalk_ir::OpaqueTyId<Interner>; |
67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; | 67 | pub type PlaceholderIndex = chalk_ir::PlaceholderIndex; |
68 | 68 | ||
69 | pub type VariableKind = chalk_ir::VariableKind<Interner>; | ||
70 | pub type VariableKinds = chalk_ir::VariableKinds<Interner>; | ||
69 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; | 71 | pub type CanonicalVarKinds = chalk_ir::CanonicalVarKinds<Interner>; |
70 | 72 | ||
71 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; | 73 | pub type ChalkTraitId = chalk_ir::TraitId<Interner>; |
@@ -78,8 +80,8 @@ impl ProjectionTy { | |||
78 | } | 80 | } |
79 | } | 81 | } |
80 | 82 | ||
81 | pub fn self_type_parameter(&self) -> &Ty { | 83 | pub fn self_type_parameter(&self, interner: &Interner) -> &Ty { |
82 | &self.substitution.interned()[0].assert_ty_ref(&Interner) | 84 | &self.substitution.interned()[0].assert_ty_ref(interner) |
83 | } | 85 | } |
84 | 86 | ||
85 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { | 87 | fn trait_(&self, db: &dyn HirDatabase) -> TraitId { |
@@ -118,55 +120,37 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
118 | } | 120 | } |
119 | 121 | ||
120 | impl<T> Binders<T> { | 122 | impl<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 | |||
153 | impl<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 | ||
159 | impl<T: TypeWalk> Binders<T> { | 131 | impl<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 | ||
140 | pub 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 | |||
167 | impl TraitRef { | 151 | impl TraitRef { |
168 | pub fn self_type_parameter(&self) -> &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) |
170 | } | 154 | } |
171 | 155 | ||
172 | pub fn hir_trait_id(&self) -> TraitId { | 156 | pub fn hir_trait_id(&self) -> TraitId { |
@@ -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(¶meters)) | 366 | Some(sig.substitute(&Interner, ¶meters)) |
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,13 +456,15 @@ 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) => tr.self_type_parameter() == self, | 461 | WhereClause::Implemented(tr) => { |
462 | tr.self_type_parameter(&Interner) == self | ||
463 | } | ||
477 | WhereClause::AliasEq(AliasEq { | 464 | WhereClause::AliasEq(AliasEq { |
478 | alias: AliasTy::Projection(proj), | 465 | alias: AliasTy::Projection(proj), |
479 | ty: _, | 466 | ty: _, |
480 | }) => proj.self_type_parameter() == self, | 467 | }) => proj.self_type_parameter(&Interner) == self, |
481 | _ => false, | 468 | _ => false, |
482 | }) | 469 | }) |
483 | .collect_vec(); | 470 | .collect_vec(); |