From 17512fc9cffecd2b34c3219a2e8c2018864b2d3d Mon Sep 17 00:00:00 2001 From: Jack Huey Date: Tue, 1 Dec 2020 19:27:45 -0500 Subject: [PATCH] Make interned_slice_common macro and make Variances use it --- chalk-engine/src/normalize_deep.rs | 4 +- chalk-integration/src/program.rs | 4 +- chalk-ir/src/lib.rs | 166 ++++++++++++----------------- chalk-solve/src/infer/test.rs | 4 +- chalk-solve/src/infer/unify.rs | 2 +- 5 files changed, 78 insertions(+), 102 deletions(-) diff --git a/chalk-engine/src/normalize_deep.rs b/chalk-engine/src/normalize_deep.rs index 786b7e97620..4690ffceeab 100644 --- a/chalk-engine/src/normalize_deep.rs +++ b/chalk-engine/src/normalize_deep.rs @@ -120,11 +120,11 @@ mod test { struct TestDatabase; impl UnificationDatabase for TestDatabase { fn fn_def_variance(&self, _fn_def_id: FnDefId) -> Variances { - Variances::from(&ChalkIr, [Variance::Invariant; 20].iter().copied()) + Variances::from_iter(&ChalkIr, [Variance::Invariant; 20].iter().copied()) } fn adt_variance(&self, _adt_id: AdtId) -> Variances { - Variances::from(&ChalkIr, [Variance::Invariant; 20].iter().copied()) + Variances::from_iter(&ChalkIr, [Variance::Invariant; 20].iter().copied()) } } diff --git a/chalk-integration/src/program.rs b/chalk-integration/src/program.rs index 398c2a9308f..a77d5d1915e 100644 --- a/chalk-integration/src/program.rs +++ b/chalk-integration/src/program.rs @@ -368,14 +368,14 @@ impl tls::DebugContext for Program { impl UnificationDatabase for Program { fn fn_def_variance(&self, fn_def_id: FnDefId) -> Variances { - Variances::from( + Variances::from_iter( self.interner(), self.fn_def_variances[&fn_def_id].iter().copied(), ) } fn adt_variance(&self, adt_id: AdtId) -> Variances { - Variances::from(self.interner(), self.adt_variances[&adt_id].iter().copied()) + Variances::from_iter(self.interner(), self.adt_variances[&adt_id].iter().copied()) } } diff --git a/chalk-ir/src/lib.rs b/chalk-ir/src/lib.rs index 89f69bed9d6..8fc2df88140 100644 --- a/chalk-ir/src/lib.rs +++ b/chalk-ir/src/lib.rs @@ -2420,70 +2420,6 @@ impl ProgramClause { } } -/// List of variable kinds with universe index. Wraps `InternedCanonicalVarKinds`. -#[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)] -pub struct Variances { - interned: I::InternedVariances, -} - -impl Variances { - /// Creates an empty list of canonical variable kinds. - pub fn empty(interner: &I) -> Self { - Self::from(interner, None::) - } - - /// Get the interned canonical variable kinds. - pub fn interned(&self) -> &I::InternedVariances { - &self.interned - } - - /// Creates a list of canonical variable kinds using an iterator. - pub fn from(interner: &I, variances: impl IntoIterator) -> Self { - Self::from_fallible( - interner, - variances - .into_iter() - .map(|p| -> Result { Ok(p) }), - ) - .unwrap() - } - - /// Tries to create a list of canonical variable kinds using an iterator. - pub fn from_fallible( - interner: &I, - variances: impl IntoIterator>, - ) -> Result { - Ok(Variances { - interned: I::intern_variances(interner, variances.into_iter())?, - }) - } - - /// Creates a list of canonical variable kinds from a single canonical variable kind. - pub fn from1(interner: &I, variance: Variance) -> Self { - Self::from(interner, Some(variance)) - } - - /// Get an iterator over the list of canonical variable kinds. - pub fn iter(&self, interner: &I) -> std::slice::Iter<'_, Variance> { - self.as_slice(interner).iter() - } - - /// Checks whether the list of canonical variable kinds is empty. - pub fn is_empty(&self, interner: &I) -> bool { - self.as_slice(interner).is_empty() - } - - /// Returns the number of canonical variable kinds. - pub fn len(&self, interner: &I) -> usize { - self.as_slice(interner).len() - } - - /// Returns a slice containing the canonical variable kinds. - pub fn as_slice(&self, interner: &I) -> &[Variance] { - interner.variances_data(&self.interned) - } -} - /// Wraps a "canonicalized item". Items are canonicalized as follows: /// /// All unresolved existential variables are "renumbered" according to their @@ -2947,7 +2883,7 @@ impl<'i, I: Interner> Folder<'i, I> for &SubstFolder<'i, I> { } } -macro_rules! interned_slice { +macro_rules! interned_slice_common { ($seq:ident, $data:ident => $elem:ty, $intern:ident => $interned:ident) => { /// List of interned elements. #[derive(Copy, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, HasInterner)] @@ -2960,7 +2896,43 @@ macro_rules! interned_slice { pub fn interned(&self) -> &I::$interned { &self.interned } + + /// Returns a slice containing the elements. + pub fn as_slice(&self, interner: &I) -> &[$elem] { + Interner::$data(interner, &self.interned) + } + + /// Index into the sequence. + pub fn at(&self, interner: &I, index: usize) -> &$elem { + &self.as_slice(interner)[index] + } + + /// Create an empty sequence. + pub fn empty(interner: &I) -> Self { + Self::from_iter(interner, None::<$elem>) + } + + /// Check whether this is an empty sequence. + pub fn is_empty(&self, interner: &I) -> bool { + self.as_slice(interner).is_empty() + } + + /// Get an iterator over the elements of the sequence. + pub fn iter(&self, interner: &I) -> std::slice::Iter<'_, $elem> { + self.as_slice(interner).iter() + } + + /// Get the length of the sequence. + pub fn len(&self, interner: &I) -> usize { + self.as_slice(interner).len() + } } + }; +} + +macro_rules! interned_slice { + ($seq:ident, $data:ident => $elem:ty, $intern:ident => $interned:ident) => { + interned_slice_common!($seq, $data => $elem, $intern => $interned); impl $seq { /// Tries to create a sequence using an iterator of element-like things. @@ -2973,11 +2945,6 @@ macro_rules! interned_slice { }) } - /// Returns a slice containing the elements. - pub fn as_slice(&self, interner: &I) -> &[$elem] { - Interner::$data(interner, &self.interned) - } - /// Create a sequence from elements pub fn from_iter( interner: &I, @@ -2992,35 +2959,10 @@ macro_rules! interned_slice { .unwrap() } - /// Index into the sequence. - pub fn at(&self, interner: &I, index: usize) -> &$elem { - &self.as_slice(interner)[index] - } - /// Create a sequence from a single element. pub fn from1(interner: &I, element: impl CastTo<$elem>) -> Self { Self::from_iter(interner, Some(element)) } - - /// Create an empty sequence. - pub fn empty(interner: &I) -> Self { - Self::from_iter(interner, None::<$elem>) - } - - /// Check whether this is an empty sequence. - pub fn is_empty(&self, interner: &I) -> bool { - self.as_slice(interner).is_empty() - } - - /// Get an iterator over the elements of the sequence. - pub fn iter(&self, interner: &I) -> std::slice::Iter<'_, $elem> { - self.as_slice(interner).iter() - } - - /// Get the length of the sequence. - pub fn len(&self, interner: &I) -> usize { - self.as_slice(interner).len() - } } }; } @@ -3063,6 +3005,40 @@ interned_slice!( intern_substitution => InternedSubstitution ); +interned_slice_common!( + Variances, + variances_data => Variance, + intern_variance => InternedVariances +); + +impl Variances { + /// Tries to create a list of canonical variable kinds using an iterator. + pub fn from_fallible( + interner: &I, + variances: impl IntoIterator>, + ) -> Result { + Ok(Variances { + interned: I::intern_variances(interner, variances.into_iter())?, + }) + } + + /// Creates a list of canonical variable kinds using an iterator. + pub fn from_iter(interner: &I, variances: impl IntoIterator) -> Self { + Self::from_fallible( + interner, + variances + .into_iter() + .map(|p| -> Result { Ok(p) }), + ) + .unwrap() + } + + /// Creates a list of canonical variable kinds from a single canonical variable kind. + pub fn from1(interner: &I, variance: Variance) -> Self { + Self::from_iter(interner, Some(variance)) + } +} + /// Combines a substitution (`subst`) with a set of region constraints /// (`constraints`). This represents the result of a query; the /// substitution stores the values for the query's unknown variables, diff --git a/chalk-solve/src/infer/test.rs b/chalk-solve/src/infer/test.rs index c3a697248d4..ddf09037b94 100644 --- a/chalk-solve/src/infer/test.rs +++ b/chalk-solve/src/infer/test.rs @@ -11,11 +11,11 @@ use chalk_integration::{arg, lifetime, ty}; struct TestDatabase; impl UnificationDatabase for TestDatabase { fn fn_def_variance(&self, _fn_def_id: FnDefId) -> Variances { - Variances::from(&ChalkIr, [Variance::Invariant; 20].iter().copied()) + Variances::from_iter(&ChalkIr, [Variance::Invariant; 20].iter().copied()) } fn adt_variance(&self, _adt_id: AdtId) -> Variances { - Variances::from(&ChalkIr, [Variance::Invariant; 20].iter().copied()) + Variances::from_iter(&ChalkIr, [Variance::Invariant; 20].iter().copied()) } } diff --git a/chalk-solve/src/infer/unify.rs b/chalk-solve/src/infer/unify.rs index dda68f45575..22df33c07ff 100644 --- a/chalk-solve/src/infer/unify.rs +++ b/chalk-solve/src/infer/unify.rs @@ -223,7 +223,7 @@ impl<'t, I: Interner> Unifier<'t, I> { } self.zip_substs( variance, - Some(Variances::from( + Some(Variances::from_iter( &self.interner, std::iter::repeat(Variance::Covariant).take(*arity_a), )),