Skip to content

Commit 5a90d4e

Browse files
committed
Changed Forest::any_future_answer to take an answer index.
This allows us to replace an ad-hoc and probably wrong special case with something that is actually very sensible.
1 parent 18bde40 commit 5a90d4e

File tree

5 files changed

+38
-19
lines changed

5 files changed

+38
-19
lines changed

chalk-engine/src/context/mod.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ crate mod prelude;
88

99
/// The "context" in which the SLG solver operates.
1010
pub trait Context: Sized + Clone + Debug + ContextOps<Self> + AggregateOps<Self> {
11-
type CanonicalExClause: Debug;
11+
type CanonicalExClause: CanonicalExClause<Self>;
1212

1313
/// A map between universes. These are produced when
1414
/// u-canonicalizing something; they map canonical results back to
@@ -21,6 +21,10 @@ pub trait Context: Sized + Clone + Debug + ContextOps<Self> + AggregateOps<Self>
2121
/// [the rustc-guide]: https://rust-lang-nursery.github.io/rustc-guide/traits-canonicalization.html#canonicalizing-the-query-result
2222
type CanonicalConstrainedSubst: CanonicalConstrainedSubst<Self>;
2323

24+
/// Extracted from a canonicalized substitution or canonicalized ex clause, this is the type of
25+
/// substitution that is fully normalized with respect to inference variables.
26+
type InferenceNormalizedSubst: Debug;
27+
2428
/// A canonicalized `GoalInEnvironment` -- that is, one where all
2529
/// free inference variables have been bound into the canonical
2630
/// binder. See [the rustc-guide] for more information.
@@ -285,9 +289,17 @@ pub trait Environment<C: Context, I: InferenceContext<C>>: Debug + Clone {
285289
fn add_clauses(&self, clauses: impl IntoIterator<Item = I::ProgramClause>) -> Self;
286290
}
287291

292+
pub trait CanonicalExClause<C: Context>: Debug {
293+
/// Extracts the inner normalized substitution.
294+
fn inference_normalized_subst(&self) -> C::InferenceNormalizedSubst;
295+
}
296+
288297
pub trait CanonicalConstrainedSubst<C: Context>: Clone + Debug + Eq + Hash + Ord {
289298
/// True if this solution has no region constraints.
290299
fn empty_constraints(&self) -> bool;
300+
301+
/// Extracts the inner normalized substitution.
302+
fn inference_normalized_subst(&self) -> C::InferenceNormalizedSubst;
291303
}
292304

293305
pub trait DomainGoal<C: Context, I: InferenceContext<C>>: Debug {
@@ -346,6 +358,6 @@ pub trait AnswerStream<C: Context> {
346358
/// if we find any answer for which `test` returns true.
347359
fn any_future_answer(
348360
&mut self,
349-
test: impl FnMut(&mut C::CanonicalExClause) -> bool,
361+
test: impl FnMut(&mut C::InferenceNormalizedSubst) -> bool,
350362
) -> bool;
351363
}

chalk-engine/src/context/prelude.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ crate use super::UnificationResult;
1111
crate use super::GoalInEnvironment;
1212
crate use super::UCanonicalGoalInEnvironment;
1313
crate use super::UniverseMap;
14+
crate use super::CanonicalExClause;
1415
crate use super::CanonicalConstrainedSubst;
1516
crate use super::Goal;
1617
crate use super::DomainGoal;

chalk-engine/src/forest.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -174,8 +174,8 @@ where
174174

175175
fn any_future_answer(
176176
&mut self,
177-
test: impl FnMut(&mut C::CanonicalExClause) -> bool,
177+
test: impl FnMut(&mut C::InferenceNormalizedSubst) -> bool,
178178
) -> bool {
179-
self.forest.any_future_answer(self.table, test)
179+
self.forest.any_future_answer(self.table, self.answer, test)
180180
}
181181
}

chalk-engine/src/logic.rs

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -106,20 +106,17 @@ impl<C: Context> Forest<C> {
106106
pub(super) fn any_future_answer(
107107
&mut self,
108108
table: TableIndex,
109-
mut test: impl FnMut(&mut C::CanonicalExClause) -> bool,
109+
answer: AnswerIndex,
110+
mut test: impl FnMut(&mut C::InferenceNormalizedSubst) -> bool,
110111
) -> bool {
111-
let mut strands = self.tables[table].strands_mut();
112-
113-
// If we don't have any strands at all, then we are
114-
// intentionally conservative and say it may_invalidate.
115-
match strands.next() {
116-
None => return true,
117-
Some(strand) => if test(&mut strand.canonical_ex_clause) {
118-
return true
119-
},
112+
if let Some(answer) = self.tables[table].answer(answer) {
113+
info!("answer cached = {:?}", answer);
114+
return test(&mut answer.subst.inference_normalized_subst());
120115
}
121116

122-
strands.any(|strand| test(&mut strand.canonical_ex_clause))
117+
self.tables[table].strands_mut().any(|strand| {
118+
test(&mut strand.canonical_ex_clause.inference_normalized_subst())
119+
})
123120
}
124121

125122
/// Ensures that answer with the given index is available from the

src/solve/slg/implementation/mod.rs

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,7 @@ impl context::Context for SlgContext {
5555
type UCanonicalGoalInEnvironment = UCanonical<InEnvironment<Goal>>;
5656
type UniverseMap = UniverseMap;
5757
type CanonicalConstrainedSubst = Canonical<ConstrainedSubst>;
58+
type InferenceNormalizedSubst = Substitution;
5859
type Solution = Solution;
5960
}
6061

@@ -238,11 +239,9 @@ impl context::Environment<SlgContext, SlgContext> for Arc<Environment> {
238239
}
239240
}
240241

241-
impl Canonical<ExClause<SlgContext, SlgContext>> {
242+
impl Substitution {
242243
fn may_invalidate(&mut self, subst: &Canonical<Substitution>) -> bool {
243-
self.value
244-
.subst
245-
.parameters
244+
self.parameters
246245
.iter()
247246
.zip(&subst.value.parameters)
248247
.any(|(new, current)| MayInvalidate.aggregate_parameters(new, current))
@@ -413,10 +412,20 @@ impl context::DomainGoal<SlgContext, SlgContext> for DomainGoal {
413412
}
414413
}
415414

415+
impl context::CanonicalExClause<SlgContext> for Canonical<ExClause<SlgContext, SlgContext>> {
416+
fn inference_normalized_subst(&self) -> Substitution {
417+
self.value.subst.clone()
418+
}
419+
}
420+
416421
impl context::CanonicalConstrainedSubst<SlgContext> for Canonical<ConstrainedSubst> {
417422
fn empty_constraints(&self) -> bool {
418423
self.value.constraints.is_empty()
419424
}
425+
426+
fn inference_normalized_subst(&self) -> Substitution {
427+
self.value.subst.clone()
428+
}
420429
}
421430

422431
impl context::UCanonicalGoalInEnvironment<SlgContext> for UCanonical<InEnvironment<Goal>> {

0 commit comments

Comments
 (0)