aboutsummaryrefslogtreecommitdiff
path: root/crates/hir_ty/src/types.rs
diff options
context:
space:
mode:
Diffstat (limited to 'crates/hir_ty/src/types.rs')
-rw-r--r--crates/hir_ty/src/types.rs69
1 files changed, 64 insertions, 5 deletions
diff --git a/crates/hir_ty/src/types.rs b/crates/hir_ty/src/types.rs
index bac086318..46c705a76 100644
--- a/crates/hir_ty/src/types.rs
+++ b/crates/hir_ty/src/types.rs
@@ -12,7 +12,7 @@ use smallvec::SmallVec;
12 12
13use crate::{ 13use crate::{
14 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId, 14 AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
15 InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, 15 InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, TypeWalk, VariableKinds,
16}; 16};
17 17
18#[derive(Clone, PartialEq, Eq, Debug, Hash)] 18#[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -286,7 +286,11 @@ impl Substitution {
286 Substitution(elements.into_iter().casted(interner).collect()) 286 Substitution(elements.into_iter().casted(interner).collect())
287 } 287 }
288 288
289 // We can hopefully add this to Chalk 289 pub fn apply<T: TypeWalk>(&self, value: T, _interner: &Interner) -> T {
290 value.subst_bound_vars(self)
291 }
292
293 // Temporary helper functions, to be removed
290 pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution { 294 pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution {
291 Substitution(interned) 295 Substitution(interned)
292 } 296 }
@@ -296,10 +300,65 @@ impl Substitution {
296 } 300 }
297} 301}
298 302
299#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)] 303#[derive(Clone, PartialEq, Eq, Hash)]
300pub struct Binders<T> { 304pub struct Binders<T> {
301 pub num_binders: usize, 305 /// The binders that quantify over the value.
302 pub value: T, 306 pub binders: VariableKinds,
307 value: T,
308}
309
310impl<T> Binders<T> {
311 pub fn new(binders: VariableKinds, value: T) -> Self {
312 Self { binders, value }
313 }
314
315 pub fn empty(_interner: &Interner, value: T) -> Self {
316 crate::make_only_type_binders(0, value)
317 }
318
319 pub fn as_ref(&self) -> Binders<&T> {
320 Binders { binders: self.binders.clone(), value: &self.value }
321 }
322
323 pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
324 Binders { binders: self.binders, value: f(self.value) }
325 }
326
327 pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
328 Some(Binders { binders: self.binders, value: f(self.value)? })
329 }
330
331 pub fn skip_binders(&self) -> &T {
332 &self.value
333 }
334
335 pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) {
336 (self.value, self.binders)
337 }
338
339 /// Returns the number of binders.
340 pub fn len(&self, interner: &Interner) -> usize {
341 self.binders.len(interner)
342 }
343
344 // Temporary helper function, to be removed
345 pub fn skip_binders_mut(&mut self) -> &mut T {
346 &mut self.value
347 }
348}
349
350impl<T: Clone> Binders<&T> {
351 pub fn cloned(&self) -> Binders<T> {
352 Binders::new(self.binders.clone(), self.value.clone())
353 }
354}
355
356impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> {
357 fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
358 let Binders { ref binders, ref value } = *self;
359 write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?;
360 std::fmt::Debug::fmt(value, fmt)
361 }
303} 362}
304 363
305/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait. 364/// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.