Skip to content

Commit 234b855

Browse files
committed
intern the parameter list
It is constructed from an iterator over results
1 parent 2042706 commit 234b855

File tree

5 files changed

+65
-13
lines changed

5 files changed

+65
-13
lines changed

chalk-ir/src/debug.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -409,7 +409,7 @@ impl<TF: TypeFamily> Substitution<TF> {
409409
/// Displays the substitution in the form `< P0, .. Pn >`, or (if
410410
/// the substitution is empty) as an empty string.
411411
pub fn with_angle(&self) -> Angle<'_, Parameter<TF>> {
412-
Angle(&self.parameters)
412+
Angle(self.parameters())
413413
}
414414
}
415415

chalk-ir/src/family.rs

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ use crate::tls;
22
use crate::AssocTypeId;
33
use crate::GoalData;
44
use crate::LifetimeData;
5+
use crate::Parameter;
56
use crate::ParameterData;
67
use crate::ProjectionTy;
78
use crate::RawId;
@@ -68,6 +69,14 @@ pub trait TypeFamily: Debug + Copy + Eq + Ord + Hash {
6869
/// converted back to its underlying data via `goal_data`.
6970
type InternedGoal: Debug + Clone + Eq + Ord + Hash;
7071

72+
/// "Interned" representation of a "substitution". In normal user code,
73+
/// `Self::InternedSubstitution` is not referenced. Instead, we refer to
74+
/// `Substitution<Self>`, which wraps this type.
75+
///
76+
/// An `InternedSubstitution` is created by `intern_substitution` and can be
77+
/// converted back to its underlying data via `substitution_data`.
78+
type InternedSubstitution: Debug + Clone + Eq + Ord + Hash;
79+
7180
/// The core "id" type used for struct-ids and the like.
7281
type DefId: Debug + Copy + Eq + Ord + Hash;
7382

@@ -146,8 +155,19 @@ pub trait TypeFamily: Debug + Copy + Eq + Ord + Hash {
146155
/// method).
147156
fn intern_goal(data: GoalData<Self>) -> Self::InternedGoal;
148157

149-
/// Lookup the `GoalData` that was interned to create a `InternedGoal`.
158+
/// Lookup the `LifetimeData` that was interned to create a `InternedLifetime`.
150159
fn goal_data(lifetime: &Self::InternedGoal) -> &GoalData<Self>;
160+
161+
/// Create an "interned" substitution from `data`. This is not
162+
/// normally invoked directly; instead, you invoke
163+
/// `SubstitutionData::intern` (which will ultimately call this
164+
/// method).
165+
fn intern_substitution<E>(
166+
data: impl IntoIterator<Item = Result<Parameter<Self>, E>>,
167+
) -> Result<Self::InternedSubstitution, E>;
168+
169+
/// Lookup the `SubstitutionData` that was interned to create a `InternedSubstitution`.
170+
fn substitution_data(lifetime: &Self::InternedSubstitution) -> &[Parameter<Self>];
151171
}
152172

153173
pub trait TargetTypeFamily<TF: TypeFamily>: TypeFamily {
@@ -181,6 +201,7 @@ impl TypeFamily for ChalkIr {
181201
type InternedLifetime = LifetimeData<ChalkIr>;
182202
type InternedParameter = ParameterData<ChalkIr>;
183203
type InternedGoal = Arc<GoalData<ChalkIr>>;
204+
type InternedSubstitution = Vec<Parameter<ChalkIr>>;
184205
type DefId = RawId;
185206

186207
fn debug_struct_id(
@@ -242,6 +263,16 @@ impl TypeFamily for ChalkIr {
242263
fn goal_data(goal: &Arc<GoalData<ChalkIr>>) -> &GoalData<ChalkIr> {
243264
goal
244265
}
266+
267+
fn intern_substitution<E>(
268+
data: impl IntoIterator<Item = Result<Parameter<ChalkIr>, E>>,
269+
) -> Result<Vec<Parameter<ChalkIr>>, E> {
270+
data.into_iter().collect()
271+
}
272+
273+
fn substitution_data(substitution: &Vec<Parameter<ChalkIr>>) -> &[Parameter<ChalkIr>] {
274+
substitution
275+
}
245276
}
246277

247278
impl HasTypeFamily for ChalkIr {

chalk-ir/src/fold/boring_impls.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@ impl<T: Fold<TF, TTF>, TF: TypeFamily, TTF: TargetTypeFamily<TF>> Fold<TF, TTF>
8686
}
8787
}
8888
}
89+
8990
impl<TF: TypeFamily, TTF: TargetTypeFamily<TF>> Fold<TF, TTF> for Parameter<TF> {
9091
type Result = Parameter<TTF>;
9192
fn fold_with(
@@ -110,6 +111,19 @@ impl<TF: TypeFamily, TTF: TargetTypeFamily<TF>> Fold<TF, TTF> for Goal<TF> {
110111
}
111112
}
112113

114+
impl<TF: TypeFamily, TTF: TargetTypeFamily<TF>> Fold<TF, TTF> for Substitution<TF> {
115+
type Result = Substitution<TTF>;
116+
fn fold_with(
117+
&self,
118+
folder: &mut dyn Folder<TF, TTF>,
119+
binders: usize,
120+
) -> Fallible<Self::Result> {
121+
Ok(Substitution::from_fallible(
122+
self.iter().map(|p| p.fold_with(folder, binders)),
123+
)?)
124+
}
125+
}
126+
113127
#[macro_export]
114128
macro_rules! copy_fold {
115129
($t:ty) => {

chalk-ir/src/lib.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1176,27 +1176,31 @@ pub enum Constraint<TF: TypeFamily> {
11761176
}
11771177

11781178
/// A mapping of inference variables to instantiations thereof.
1179-
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Fold, Hash, HasTypeFamily)]
1179+
#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, HasTypeFamily)]
11801180
pub struct Substitution<TF: TypeFamily> {
11811181
/// Map free variable with given index to the value with the same
11821182
/// index. Naturally, the kind of the variable must agree with
11831183
/// the kind of the value.
1184-
parameters: Vec<Parameter<TF>>,
1184+
parameters: TF::InternedSubstitution,
11851185
}
11861186

11871187
impl<TF: TypeFamily> Substitution<TF> {
11881188
pub fn from(parameters: impl IntoIterator<Item = impl CastTo<Parameter<TF>>>) -> Self {
1189-
use crate::cast::Caster;
1190-
let parameters = parameters.into_iter().casted().collect();
1191-
Substitution { parameters }
1189+
Self::from_fallible(
1190+
parameters
1191+
.into_iter()
1192+
.map(|p| -> Result<Parameter<TF>, ()> { Ok(p.cast()) }),
1193+
)
1194+
.unwrap()
11921195
}
11931196

11941197
pub fn from_fallible<E>(
11951198
parameters: impl IntoIterator<Item = Result<impl CastTo<Parameter<TF>>, E>>,
11961199
) -> Result<Self, E> {
11971200
use crate::cast::Caster;
1198-
let parameters: Result<Vec<Parameter<TF>>, E> = parameters.into_iter().casted().collect();
1199-
Ok(Substitution::from(parameters?))
1201+
Ok(Substitution {
1202+
parameters: TF::intern_substitution(parameters.into_iter().casted())?,
1203+
})
12001204
}
12011205

12021206
/// Index into the list of parameters
@@ -1221,7 +1225,7 @@ impl<TF: TypeFamily> Substitution<TF> {
12211225
}
12221226

12231227
pub fn parameters(&self) -> &[Parameter<TF>] {
1224-
&self.parameters
1228+
TF::substitution_data(&self.parameters)
12251229
}
12261230

12271231
pub fn len(&self) -> usize {

chalk-ir/src/zip.rs

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -179,9 +179,6 @@ macro_rules! struct_zip {
179179
}
180180
}
181181

182-
struct_zip!(impl[TF: TypeFamily] Zip<TF> for Substitution<TF> {
183-
parameters,
184-
});
185182
struct_zip!(impl[TF: TypeFamily] Zip<TF> for TraitRef<TF> {
186183
trait_id,
187184
substitution,
@@ -256,6 +253,12 @@ enum_zip!(impl<TF> for DomainGoal<TF> {
256253
});
257254
enum_zip!(impl<TF> for ProgramClause<TF> { Implies, ForAll });
258255

256+
impl<TF: TypeFamily> Zip<TF> for Substitution<TF> {
257+
fn zip_with<Z: Zipper<TF>>(zipper: &mut Z, a: &Self, b: &Self) -> Fallible<()> {
258+
Zip::zip_with(zipper, a.parameters(), b.parameters())
259+
}
260+
}
261+
259262
// Annoyingly, Goal cannot use `enum_zip` because some variants have
260263
// two parameters, and I'm too lazy to make the macro account for the
261264
// relevant name mangling.

0 commit comments

Comments
 (0)