diff options
Diffstat (limited to 'crates/hir_ty/src/lib.rs')
-rw-r--r-- | crates/hir_ty/src/lib.rs | 44 |
1 files changed, 11 insertions, 33 deletions
diff --git a/crates/hir_ty/src/lib.rs b/crates/hir_ty/src/lib.rs index adfdcaa37..61b5cf269 100644 --- a/crates/hir_ty/src/lib.rs +++ b/crates/hir_ty/src/lib.rs | |||
@@ -118,49 +118,27 @@ pub fn param_idx(db: &dyn HirDatabase, id: TypeParamId) -> Option<usize> { | |||
118 | } | 118 | } |
119 | 119 | ||
120 | impl<T> Binders<T> { | 120 | 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 | 121 | pub fn wrap_empty(value: T) -> Self |
126 | where | 122 | where |
127 | T: TypeWalk, | 123 | T: TypeWalk, |
128 | { | 124 | { |
129 | Self { num_binders: 0, value: value.shift_bound_vars(DebruijnIndex::ONE) } | 125 | Binders::empty(&Interner, value.shift_bound_vars(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 | } | 126 | } |
151 | } | 127 | } |
152 | 128 | ||
153 | impl<T: Clone> Binders<&T> { | 129 | impl<T: Clone> Binders<&T> { |
154 | pub fn cloned(&self) -> Binders<T> { | 130 | pub fn cloned(&self) -> Binders<T> { |
155 | Binders { num_binders: self.num_binders, value: self.value.clone() } | 131 | let (value, binders) = self.into_value_and_skipped_binders(); |
132 | Binders::new(binders, value.clone()) | ||
156 | } | 133 | } |
157 | } | 134 | } |
158 | 135 | ||
159 | impl<T: TypeWalk> Binders<T> { | 136 | impl<T: TypeWalk> Binders<T> { |
160 | /// Substitutes all variables. | 137 | /// Substitutes all variables. |
161 | pub fn subst(self, subst: &Substitution) -> T { | 138 | pub fn subst(self, subst: &Substitution) -> T { |
162 | assert_eq!(subst.len(&Interner), self.num_binders); | 139 | let (value, binders) = self.into_value_and_skipped_binders(); |
163 | self.value.subst_bound_vars(subst) | 140 | assert_eq!(subst.len(&Interner), binders); |
141 | value.subst_bound_vars(subst) | ||
164 | } | 142 | } |
165 | } | 143 | } |
166 | 144 | ||
@@ -334,12 +312,12 @@ impl Ty { | |||
334 | /// If this is a `dyn Trait` type, this returns the `Trait` part. | 312 | /// If this is a `dyn Trait` type, this returns the `Trait` part. |
335 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { | 313 | fn dyn_trait_ref(&self) -> Option<&TraitRef> { |
336 | match self.kind(&Interner) { | 314 | match self.kind(&Interner) { |
337 | TyKind::Dyn(dyn_ty) => { | 315 | 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() { | 316 | match b.skip_binders() { |
339 | WhereClause::Implemented(trait_ref) => Some(trait_ref), | 317 | WhereClause::Implemented(trait_ref) => Some(trait_ref), |
340 | _ => None, | 318 | _ => None, |
341 | }) | 319 | } |
342 | } | 320 | }), |
343 | _ => None, | 321 | _ => None, |
344 | } | 322 | } |
345 | } | 323 | } |
@@ -459,7 +437,7 @@ impl Ty { | |||
459 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), | 437 | ImplTraitId::AsyncBlockTypeImplTrait(..) => unreachable!(), |
460 | }; | 438 | }; |
461 | 439 | ||
462 | predicates.map(|it| it.value) | 440 | predicates.map(|it| it.into_value_and_skipped_binders().0) |
463 | } | 441 | } |
464 | TyKind::Placeholder(idx) => { | 442 | TyKind::Placeholder(idx) => { |
465 | let id = from_placeholder_idx(db, *idx); | 443 | let id = from_placeholder_idx(db, *idx); |