Skip to content

Commit 95a5bde

Browse files
committed
refactor normalize_shallow
1 parent 03b7d80 commit 95a5bde

File tree

8 files changed

+92
-96
lines changed

8 files changed

+92
-96
lines changed

chalk-ir/src/fold.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -288,7 +288,7 @@ where
288288
outer_binder: DebruijnIndex,
289289
) -> Fallible<Const<TI>> {
290290
if self.forbid_inference_vars() {
291-
panic!("unexpected inference lifetime `'{:?}`", var)
291+
panic!("unexpected inference const `{:?}`", var)
292292
} else {
293293
Ok(var.to_const(self.target_interner()))
294294
}

chalk-ir/src/lib.rs

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,7 @@ impl<I: Interner> Ty<I> {
212212
}
213213

214214
/// If this is a `TyData::BoundVar(d)`, returns `Some(d)` else `None`.
215-
pub fn bound(&self, interner: &I) -> Option<BoundVar> {
215+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
216216
if let TyData::BoundVar(bv) = self.data(interner) {
217217
Some(*bv)
218218
} else {
@@ -614,7 +614,7 @@ impl<I: Interner> Const<I> {
614614
}
615615

616616
/// If this is a `ConstData::BoundVar(d)`, returns `Some(d)` else `None`.
617-
pub fn bound(&self, interner: &I) -> Option<BoundVar> {
617+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
618618
if let ConstData::BoundVar(bv) = self.data(interner) {
619619
Some(*bv)
620620
} else {
@@ -688,6 +688,15 @@ impl<I: Interner> Lifetime<I> {
688688
I::lifetime_data(interner, &self.interned)
689689
}
690690

691+
/// If this is a `Lifetime::BoundVar(d)`, returns `Some(d)` else `None`.
692+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
693+
if let LifetimeData::BoundVar(bv) = self.data(interner) {
694+
Some(*bv)
695+
} else {
696+
None
697+
}
698+
}
699+
691700
/// If this is a `Lifetime::InferenceVar(d)`, returns `Some(d)` else `None`.
692701
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
693702
if let LifetimeData::InferenceVar(depth) = self.data(interner) {
@@ -932,6 +941,22 @@ impl<I: Interner> Parameter<I> {
932941
_ => None,
933942
}
934943
}
944+
945+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
946+
match self.data(interner) {
947+
ParameterKind::Ty(t) => t.bound_var(interner),
948+
ParameterKind::Lifetime(l) => l.bound_var(interner),
949+
ParameterKind::Const(c) => c.bound_var(interner),
950+
}
951+
}
952+
953+
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
954+
match self.data(interner) {
955+
ParameterKind::Ty(t) => t.inference_var(interner),
956+
ParameterKind::Lifetime(l) => l.inference_var(interner),
957+
ParameterKind::Const(c) => c.inference_var(interner),
958+
}
959+
}
935960
}
936961

937962
#[allow(type_alias_bounds)]

chalk-solve/src/infer.rs

Lines changed: 26 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -118,91 +118,47 @@ impl<I: Interner> InferenceTable<I> {
118118
self.unify.commit(snapshot.unify_snapshot);
119119
}
120120

121-
/// If type `leaf` is a free inference variable, and that variable has been
122-
/// bound, returns `Some(T)` where `T` is the type to which it has been bound.
123-
///
124-
/// `binders` is the number of binders under which `leaf` appears;
125-
/// the return value will also be shifted accordingly so that it
126-
/// can appear under that same number of binders.
127-
pub(crate) fn normalize_shallow(&mut self, interner: &I, leaf: &Ty<I>) -> Option<Ty<I>> {
128-
let var = EnaVariable::from(leaf.inference_var(interner)?);
129-
let ty = self.probe_ty_var(interner, var)?;
130-
assert!(!ty.needs_shift(interner));
131-
Some(ty)
121+
pub(crate) fn normalize_ty_shallow(&mut self, interner: &I, leaf: &Ty<I>) -> Option<Ty<I>> {
122+
self.probe_var(leaf.inference_var(interner)?)
123+
.map(|p| p.assert_ty_ref(interner).clone())
132124
}
133125

134-
/// If `leaf` represents an inference variable `X`, and `X` is bound,
135-
/// returns `Some(v)` where `v` is the value to which `X` is bound.
136-
pub(crate) fn normalize_lifetime(
126+
pub(crate) fn normalize_lifetime_shallow(
137127
&mut self,
138128
interner: &I,
139129
leaf: &Lifetime<I>,
140130
) -> Option<Lifetime<I>> {
141-
let var = EnaVariable::from(leaf.inference_var(interner)?);
142-
let v1 = self.probe_lifetime_var(interner, var)?;
143-
assert!(!v1.needs_shift(interner));
144-
Some(v1)
131+
self.probe_var(leaf.inference_var(interner)?)
132+
.map(|p| p.assert_lifetime_ref(interner).clone())
145133
}
146134

147-
pub(crate) fn normalize_const(&mut self, interner: &I, leaf: &Const<I>) -> Option<Const<I>> {
148-
let var = EnaVariable::from(leaf.inference_var(interner)?);
149-
let c = self.probe_const_var(interner, var)?;
150-
assert!(!c.needs_shift(interner));
151-
Some(c)
152-
}
153-
154-
/// Returns true if `var` has been bound.
155-
pub(crate) fn var_is_bound(&mut self, var: InferenceVar) -> bool {
156-
match self.unify.probe_value(EnaVariable::from(var)) {
157-
InferenceValue::Unbound(_) => false,
158-
InferenceValue::Bound(_) => true,
159-
}
160-
}
161-
162-
/// Finds the type to which `var` is bound, returning `None` if it is not yet
163-
/// bound.
164-
///
165-
/// # Panics
166-
///
167-
/// This method is only valid for inference variables of kind
168-
/// type. If this variable is of a different kind, then the
169-
/// function may panic.
170-
fn probe_ty_var(&mut self, interner: &I, var: EnaVariable<I>) -> Option<Ty<I>> {
171-
match self.unify.probe_value(var) {
172-
InferenceValue::Unbound(_) => None,
173-
InferenceValue::Bound(ref val) => Some(val.as_ref(interner).ty().unwrap().clone()),
174-
}
135+
pub(crate) fn normalize_const_shallow(
136+
&mut self,
137+
interner: &I,
138+
leaf: &Const<I>,
139+
) -> Option<Const<I>> {
140+
self.probe_var(leaf.inference_var(interner)?)
141+
.map(|p| p.assert_const_ref(interner).clone())
175142
}
176143

177-
/// Finds the lifetime to which `var` is bound, returning `None` if it is not yet
178-
/// bound.
179-
///
180-
/// # Panics
144+
/// If type `leaf` is a free inference variable, and that variable has been
145+
/// bound, returns `Some(T)` where `T` is the type to which it has been bound.
181146
///
182-
/// This method is only valid for inference variables of kind
183-
/// lifetime. If this variable is of a different kind, then the function may panic.
184-
fn probe_lifetime_var(&mut self, interner: &I, var: EnaVariable<I>) -> Option<Lifetime<I>> {
185-
match self.unify.probe_value(var) {
147+
/// `binders` is the number of binders under which `leaf` appears;
148+
/// the return value will also be shifted accordingly so that it
149+
/// can appear under that same number of binders.
150+
pub(crate) fn probe_var(&mut self, leaf: InferenceVar) -> Option<Parameter<I>> {
151+
match self.unify.probe_value(EnaVariable::from(leaf)) {
186152
InferenceValue::Unbound(_) => None,
187-
InferenceValue::Bound(ref val) => {
188-
Some(val.as_ref(interner).lifetime().unwrap().clone())
189-
}
153+
InferenceValue::Bound(ref val) => Some(val.clone()),
190154
}
191155
}
192156

193-
/// Finds the const to which `var` is bound, returning `None` if it is not yet
194-
/// bound.
195-
///
196-
/// # Panics
197-
///
198-
/// This method is only valid for inference variables of kind
199-
/// const. If this variable is of a different kind, then the function may panic.
200-
fn probe_const_var(&mut self, interner: &I, var: EnaVariable<I>) -> Option<Const<I>> {
201-
match self.unify.probe_value(var) {
202-
InferenceValue::Unbound(_) => None,
203-
InferenceValue::Bound(ref val) => {
204-
Some(val.as_ref(interner).constant().unwrap().clone())
205-
}
157+
/// Returns true if `var` has been bound.
158+
pub(crate) fn var_is_bound(&mut self, var: InferenceVar) -> bool {
159+
match self.unify.probe_value(EnaVariable::from(var)) {
160+
InferenceValue::Unbound(_) => false,
161+
InferenceValue::Bound(_) => true,
206162
}
207163
}
208164

chalk-solve/src/infer/canonicalize.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use chalk_ir::interner::{HasInterner, Interner};
55
use chalk_ir::*;
66
use std::cmp::max;
77

8-
use super::{EnaVariable, InferenceTable, ParameterEnaVariable};
8+
use super::{InferenceTable, ParameterEnaVariable};
99

1010
impl<I: Interner> InferenceTable<I> {
1111
/// Given a value `value` with variables in it, replaces those variables
@@ -149,9 +149,9 @@ where
149149
outer_binder
150150
);
151151
let interner = self.interner;
152-
let var = EnaVariable::from(var);
153-
match self.table.probe_ty_var(interner, var) {
152+
match self.table.probe_var(var) {
154153
Some(ty) => {
154+
let ty = ty.assert_ty_ref(interner);
155155
debug!("bound to {:?}", ty);
156156
Ok(ty
157157
.fold_with(self, DebruijnIndex::INNERMOST)?
@@ -181,9 +181,9 @@ where
181181
outer_binder
182182
);
183183
let interner = self.interner;
184-
let var = EnaVariable::from(var);
185-
match self.table.probe_lifetime_var(interner, var) {
184+
match self.table.probe_var(var) {
186185
Some(l) => {
186+
let l = l.assert_lifetime_ref(interner);
187187
debug!("bound to {:?}", l);
188188
Ok(l.fold_with(self, DebruijnIndex::INNERMOST)?
189189
.shifted_in_from(interner, outer_binder))
@@ -211,9 +211,9 @@ where
211211
outer_binder
212212
);
213213
let interner = self.interner;
214-
let var = EnaVariable::from(var);
215-
match self.table.probe_const_var(interner, var) {
214+
match self.table.probe_var(var) {
216215
Some(c) => {
216+
let c = c.assert_const_ref(interner);
217217
debug!("bound to {:?}", c);
218218
Ok(c.fold_with(self, DebruijnIndex::INNERMOST)?
219219
.shifted_in_from(interner, outer_binder))

chalk-solve/src/infer/normalize_deep.rs

Lines changed: 20 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ use chalk_ir::fold::{Fold, Folder};
44
use chalk_ir::interner::Interner;
55
use chalk_ir::*;
66

7-
use super::{EnaVariable, InferenceTable};
7+
use super::InferenceTable;
88

99
impl<I: Interner> InferenceTable<I> {
1010
/// Given a value `value` with variables in it, replaces those variables
@@ -50,9 +50,9 @@ where
5050
_outer_binder: DebruijnIndex,
5151
) -> Fallible<Ty<I>> {
5252
let interner = self.interner;
53-
let var = EnaVariable::from(var);
54-
match self.table.probe_ty_var(interner, var) {
53+
match self.table.probe_var(var) {
5554
Some(ty) => Ok(ty
55+
.assert_ty_ref(interner)
5656
.fold_with(self, DebruijnIndex::INNERMOST)?
5757
.shifted_in(interner)), // FIXME shift
5858
None => Ok(var.to_ty(interner)),
@@ -65,15 +65,30 @@ where
6565
_outer_binder: DebruijnIndex,
6666
) -> Fallible<Lifetime<I>> {
6767
let interner = self.interner;
68-
let var = EnaVariable::from(var);
69-
match self.table.probe_lifetime_var(interner, var) {
68+
match self.table.probe_var(var) {
7069
Some(l) => Ok(l
70+
.assert_lifetime_ref(interner)
7171
.fold_with(self, DebruijnIndex::INNERMOST)?
7272
.shifted_in(interner)),
7373
None => Ok(var.to_lifetime(interner)), // FIXME shift
7474
}
7575
}
7676

77+
fn fold_inference_const(
78+
&mut self,
79+
var: InferenceVar,
80+
_outer_binder: DebruijnIndex,
81+
) -> Fallible<Const<I>> {
82+
let interner = self.interner;
83+
match self.table.probe_var(var) {
84+
Some(c) => Ok(c
85+
.assert_const_ref(interner)
86+
.fold_with(self, DebruijnIndex::INNERMOST)?
87+
.shifted_in(interner)),
88+
None => Ok(var.to_const(interner)), // FIXME shift
89+
}
90+
}
91+
7792
fn forbid_free_vars(&self) -> bool {
7893
true
7994
}

chalk-solve/src/infer/unify.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -85,9 +85,9 @@ impl<'t, I: Interner> Unifier<'t, I> {
8585
fn unify_ty_ty<'a>(&mut self, a: &'a Ty<I>, b: &'a Ty<I>) -> Fallible<()> {
8686
let interner = self.interner;
8787
// ^^ ^^ ^^ FIXME rustc bug
88-
if let Some(n_a) = self.table.normalize_shallow(interner, a) {
88+
if let Some(n_a) = self.table.normalize_ty_shallow(interner, a) {
8989
return self.unify_ty_ty(&n_a, b);
90-
} else if let Some(n_b) = self.table.normalize_shallow(interner, b) {
90+
} else if let Some(n_b) = self.table.normalize_ty_shallow(interner, b) {
9191
return self.unify_ty_ty(a, &n_b);
9292
}
9393

@@ -272,9 +272,9 @@ impl<'t, I: Interner> Unifier<'t, I> {
272272
fn unify_lifetime_lifetime(&mut self, a: &Lifetime<I>, b: &Lifetime<I>) -> Fallible<()> {
273273
let interner = self.interner;
274274

275-
if let Some(n_a) = self.table.normalize_lifetime(interner, a) {
275+
if let Some(n_a) = self.table.normalize_lifetime_shallow(interner, a) {
276276
return self.unify_lifetime_lifetime(&n_a, b);
277-
} else if let Some(n_b) = self.table.normalize_lifetime(interner, b) {
277+
} else if let Some(n_b) = self.table.normalize_lifetime_shallow(interner, b) {
278278
return self.unify_lifetime_lifetime(a, &n_b);
279279
}
280280

@@ -336,9 +336,9 @@ impl<'t, I: Interner> Unifier<'t, I> {
336336
fn unify_const_const<'a>(&mut self, a: &'a Const<I>, b: &'a Const<I>) -> Fallible<()> {
337337
let interner = self.interner;
338338

339-
if let Some(n_a) = self.table.normalize_const(interner, a) {
339+
if let Some(n_a) = self.table.normalize_const_shallow(interner, a) {
340340
return self.unify_const_const(&n_a, b);
341-
} else if let Some(n_b) = self.table.normalize_const(interner, b) {
341+
} else if let Some(n_b) = self.table.normalize_const_shallow(interner, b) {
342342
return self.unify_const_const(a, &n_b);
343343
}
344344

chalk-solve/src/solve/slg/aggregate.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -198,8 +198,8 @@ fn is_trivial<I: Interner>(interner: &I, subst: &Canonical<Substitution<I>>) ->
198198
// All types and consts are mapped to distinct variables. Since this
199199
// has been canonicalized, those will also be the first N
200200
// variables.
201-
ParameterKind::Ty(t) => is_trivial(t.bound(interner)),
202-
ParameterKind::Const(t) => is_trivial(t.bound(interner)),
201+
ParameterKind::Ty(t) => is_trivial(t.bound_var(interner)),
202+
ParameterKind::Const(t) => is_trivial(t.bound_var(interner)),
203203

204204
// And no lifetime mappings. (This is too strict, but we never
205205
// product substs with lifetimes.)

chalk-solve/src/solve/slg/resolvent.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -385,7 +385,7 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
385385
fn zip_tys(&mut self, answer: &Ty<I>, pending: &Ty<I>) -> Fallible<()> {
386386
let interner = self.interner;
387387

388-
if let Some(pending) = self.table.normalize_shallow(interner, pending) {
388+
if let Some(pending) = self.table.normalize_ty_shallow(interner, pending) {
389389
return Zip::zip_with(self, answer, &pending);
390390
}
391391

@@ -442,7 +442,7 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
442442

443443
fn zip_lifetimes(&mut self, answer: &Lifetime<I>, pending: &Lifetime<I>) -> Fallible<()> {
444444
let interner = self.interner;
445-
if let Some(pending) = self.table.normalize_lifetime(interner, pending) {
445+
if let Some(pending) = self.table.normalize_lifetime_shallow(interner, pending) {
446446
return Zip::zip_with(self, answer, &pending);
447447
}
448448

@@ -482,7 +482,7 @@ impl<'i, I: Interner> Zipper<'i, I> for AnswerSubstitutor<'i, I> {
482482

483483
fn zip_consts(&mut self, answer: &Const<I>, pending: &Const<I>) -> Fallible<()> {
484484
let interner = self.interner;
485-
if let Some(pending) = self.table.normalize_const(interner, pending) {
485+
if let Some(pending) = self.table.normalize_const_shallow(interner, pending) {
486486
return Zip::zip_with(self, answer, &pending);
487487
}
488488

0 commit comments

Comments
 (0)