Skip to content

Commit 2d4f06c

Browse files
committed
refactor normalize_shallow
1 parent f72d965 commit 2d4f06c

File tree

9 files changed

+93
-97
lines changed

9 files changed

+93
-97
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
@@ -209,7 +209,7 @@ impl<I: Interner> Ty<I> {
209209
}
210210

211211
/// If this is a `TyData::BoundVar(d)`, returns `Some(d)` else `None`.
212-
pub fn bound(&self, interner: &I) -> Option<BoundVar> {
212+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
213213
if let TyData::BoundVar(bv) = self.data(interner) {
214214
Some(*bv)
215215
} else {
@@ -611,7 +611,7 @@ impl<I: Interner> Const<I> {
611611
}
612612

613613
/// If this is a `ConstData::BoundVar(d)`, returns `Some(d)` else `None`.
614-
pub fn bound(&self, interner: &I) -> Option<BoundVar> {
614+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
615615
if let ConstData::BoundVar(bv) = self.data(interner) {
616616
Some(*bv)
617617
} else {
@@ -685,6 +685,15 @@ impl<I: Interner> Lifetime<I> {
685685
I::lifetime_data(interner, &self.interned)
686686
}
687687

688+
/// If this is a `Lifetime::BoundVar(d)`, returns `Some(d)` else `None`.
689+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
690+
if let LifetimeData::BoundVar(bv) = self.data(interner) {
691+
Some(*bv)
692+
} else {
693+
None
694+
}
695+
}
696+
688697
/// If this is a `Lifetime::InferenceVar(d)`, returns `Some(d)` else `None`.
689698
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
690699
if let LifetimeData::InferenceVar(depth) = self.data(interner) {
@@ -929,6 +938,22 @@ impl<I: Interner> Parameter<I> {
929938
_ => None,
930939
}
931940
}
941+
942+
pub fn bound_var(&self, interner: &I) -> Option<BoundVar> {
943+
match self.data(interner) {
944+
ParameterKind::Ty(t) => t.bound_var(interner),
945+
ParameterKind::Lifetime(l) => l.bound_var(interner),
946+
ParameterKind::Const(c) => c.bound_var(interner),
947+
}
948+
}
949+
950+
pub fn inference_var(&self, interner: &I) -> Option<InferenceVar> {
951+
match self.data(interner) {
952+
ParameterKind::Ty(t) => t.inference_var(interner),
953+
ParameterKind::Lifetime(l) => l.inference_var(interner),
954+
ParameterKind::Const(c) => c.inference_var(interner),
955+
}
956+
}
932957
}
933958

934959
#[allow(type_alias_bounds)]

chalk-solve/src/infer.rs

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

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

139-
/// If `leaf` represents an inference variable `X`, and `X` is bound,
140-
/// returns `Some(v)` where `v` is the value to which `X` is bound.
141-
pub(crate) fn normalize_lifetime(
131+
pub(crate) fn normalize_lifetime_shallow(
142132
&mut self,
143133
interner: &I,
144134
leaf: &Lifetime<I>,
145135
) -> Option<Lifetime<I>> {
146-
let var = EnaVariable::from(leaf.inference_var(interner)?);
147-
let v1 = self.probe_lifetime_var(interner, var)?;
148-
assert!(!v1.needs_shift(interner));
149-
Some(v1)
136+
self.probe_var(leaf.inference_var(interner)?)
137+
.map(|p| p.assert_lifetime_ref(interner).clone())
150138
}
151139

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

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

198-
/// Finds the const to which `var` is bound, returning `None` if it is not yet
199-
/// bound.
200-
///
201-
/// # Panics
202-
///
203-
/// This method is only valid for inference variables of kind
204-
/// const. If this variable is of a different kind, then the function may panic.
205-
fn probe_const_var(&mut self, interner: &I, var: EnaVariable<I>) -> Option<Const<I>> {
206-
match self.unify.probe_value(var) {
207-
InferenceValue::Unbound(_) => None,
208-
InferenceValue::Bound(ref val) => {
209-
Some(val.as_ref(interner).constant().unwrap().clone())
210-
}
162+
/// Returns true if `var` has been bound.
163+
pub(crate) fn var_is_bound(&mut self, var: InferenceVar) -> bool {
164+
match self.unify.probe_value(EnaVariable::from(var)) {
165+
InferenceValue::Unbound(_) => false,
166+
InferenceValue::Bound(_) => true,
211167
}
212168
}
213169

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

chalk-solve/src/solve/truncate.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@ where
8282
}
8383

8484
fn fold_ty(&mut self, ty: &Ty<I>, outer_binder: DebruijnIndex) -> Fallible<Ty<I>> {
85-
if let Some(normalized_ty) = self.infer.normalize_shallow(self.interner, ty) {
85+
if let Some(normalized_ty) = self.infer.normalize_ty_shallow(self.interner, ty) {
8686
return self.fold_ty(&normalized_ty, outer_binder);
8787
}
8888

0 commit comments

Comments
 (0)