]> git.lizzy.rs Git - rust.git/blobdiff - crates/hir_ty/src/types.rs
Use VariableKinds in Binders
[rust.git] / crates / hir_ty / src / types.rs
index 0e3dd511f9d91fa872cff4cd29409e6b83f9a639..59678b45b41b154adf30cd324855295cda75ed5c 100644 (file)
@@ -12,7 +12,7 @@
 
 use crate::{
     AssocTypeId, CanonicalVarKinds, ChalkTraitId, ClosureId, FnDefId, FnSig, ForeignDefId,
-    InferenceVar, Interner, OpaqueTyId, PlaceholderIndex,
+    InferenceVar, Interner, OpaqueTyId, PlaceholderIndex, VariableKinds,
 };
 
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
@@ -286,7 +286,7 @@ pub fn from_iter(
         Substitution(elements.into_iter().casted(interner).collect())
     }
 
-    // We can hopefully add this to Chalk
+    // Temporary helper functions, to be removed
     pub fn intern(interned: SmallVec<[GenericArg; 2]>) -> Substitution {
         Substitution(interned)
     }
@@ -296,46 +296,67 @@ pub fn from_iter(
     }
 }
 
-#[derive(Copy, Clone, PartialEq, Eq, Debug, Hash)]
+#[derive(Clone, PartialEq, Eq, Hash)]
 pub struct Binders<T> {
-    pub num_binders: usize,
+    /// The binders that quantify over the value.
+    pub binders: VariableKinds,
     value: T,
 }
 
 impl<T> Binders<T> {
-    pub fn new(num_binders: usize, value: T) -> Self {
-        Self { num_binders, value }
+    pub fn new(binders: VariableKinds, value: T) -> Self {
+        Self { binders, value }
     }
 
     pub fn empty(_interner: &Interner, value: T) -> Self {
-        Self { num_binders: 0, value }
+        crate::make_only_type_binders(0, value)
     }
 
     pub fn as_ref(&self) -> Binders<&T> {
-        Binders { num_binders: self.num_binders, value: &self.value }
+        Binders { binders: self.binders.clone(), value: &self.value }
     }
 
     pub fn map<U>(self, f: impl FnOnce(T) -> U) -> Binders<U> {
-        Binders { num_binders: self.num_binders, value: f(self.value) }
+        Binders { binders: self.binders, value: f(self.value) }
     }
 
     pub fn filter_map<U>(self, f: impl FnOnce(T) -> Option<U>) -> Option<Binders<U>> {
-        Some(Binders { num_binders: self.num_binders, value: f(self.value)? })
+        Some(Binders { binders: self.binders, value: f(self.value)? })
     }
 
     pub fn skip_binders(&self) -> &T {
         &self.value
     }
 
-    pub fn into_value_and_skipped_binders(self) -> (T, usize) {
-        (self.value, self.num_binders)
+    pub fn into_value_and_skipped_binders(self) -> (T, VariableKinds) {
+        (self.value, self.binders)
     }
 
+    /// Returns the number of binders.
+    pub fn len(&self, interner: &Interner) -> usize {
+        self.binders.len(interner)
+    }
+
+    // Temporary helper function, to be removed
     pub fn skip_binders_mut(&mut self) -> &mut T {
         &mut self.value
     }
 }
 
+impl<T: Clone> Binders<&T> {
+    pub fn cloned(&self) -> Binders<T> {
+        Binders::new(self.binders.clone(), self.value.clone())
+    }
+}
+
+impl<T: std::fmt::Debug> std::fmt::Debug for Binders<T> {
+    fn fmt(&self, fmt: &mut std::fmt::Formatter<'_>) -> Result<(), std::fmt::Error> {
+        let Binders { ref binders, ref value } = *self;
+        write!(fmt, "for{:?} ", binders.inner_debug(&Interner))?;
+        std::fmt::Debug::fmt(value, fmt)
+    }
+}
+
 /// A trait with type parameters. This includes the `Self`, so this represents a concrete type implementing the trait.
 #[derive(Clone, PartialEq, Eq, Debug, Hash)]
 pub struct TraitRef {