Skip to content

Commit 06b952e

Browse files
committed
Never truncate goal
1 parent 469b528 commit 06b952e

File tree

3 files changed

+31
-27
lines changed

3 files changed

+31
-27
lines changed

chalk-engine/src/logic.rs

Lines changed: 13 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@ use crate::table::AnswerIndex;
77
use crate::{
88
Answer, CompleteAnswer, ExClause, FlounderedSubgoal, Literal, Minimums, TableIndex, TimeStamp,
99
};
10-
use std::mem;
1110

1211
type RootSearchResult<T> = Result<T, RootSearchFail>;
1312

@@ -282,7 +281,7 @@ impl<C: Context> Forest<C> {
282281
) {
283282
Ok(()) => {
284283
let Strand {
285-
infer,
284+
infer: _,
286285
ex_clause,
287286
selected_subgoal: _,
288287
last_pursued_time: _,
@@ -1177,7 +1176,7 @@ impl<C: Context> Forest<C> {
11771176

11781177
// Subgoal abstraction:
11791178
let (ucanonical_subgoal, universe_map) = match subgoal {
1180-
Literal::Positive(subgoal) => self.abstract_positive_literal(infer, subgoal),
1179+
Literal::Positive(subgoal) => self.abstract_positive_literal(infer, subgoal)?,
11811180
Literal::Negative(subgoal) => self.abstract_negative_literal(infer, subgoal)?,
11821181
};
11831182

@@ -1317,7 +1316,7 @@ impl<C: Context> Forest<C> {
13171316
&mut self,
13181317
infer: &mut dyn InferenceTable<C>,
13191318
subgoal: &C::GoalInEnvironment,
1320-
) -> (C::UCanonicalGoalInEnvironment, C::UniverseMap) {
1319+
) -> Option<(C::UCanonicalGoalInEnvironment, C::UniverseMap)> {
13211320
// Subgoal abstraction: Rather than looking up the table for
13221321
// `selected_goal` directly, first apply the truncation
13231322
// function. This may introduce fresh variables, making the
@@ -1341,13 +1340,12 @@ impl<C: Context> Forest<C> {
13411340
// irrelevant answers (e.g., `Vec<Vec<u32>>: Sized`), they
13421341
// will fail to unify with our selected goal, producing no
13431342
// resolvent.
1344-
match infer.truncate_goal(subgoal) {
1345-
None => infer.fully_canonicalize_goal(subgoal),
1346-
Some(truncated_subgoal) => {
1347-
debug!("truncated={:?}", truncated_subgoal);
1348-
infer.fully_canonicalize_goal(&truncated_subgoal)
1349-
}
1343+
1344+
if infer.truncate_goal(subgoal).is_some() {
1345+
return None;
13501346
}
1347+
1348+
return Some(infer.fully_canonicalize_goal(subgoal));
13511349
}
13521350

13531351
/// Given a selected negative subgoal, the subgoal is "inverted"
@@ -1452,10 +1450,12 @@ impl<C: Context> Forest<C> {
14521450
// variables that have been inverted, as discussed in the
14531451
// prior paragraph above.) I just didn't feel like dealing
14541452
// with it yet.
1455-
match infer.truncate_goal(&inverted_subgoal) {
1456-
Some(_) => None,
1457-
None => Some(infer.fully_canonicalize_goal(&inverted_subgoal)),
1453+
1454+
if infer.truncate_goal(&inverted_subgoal).is_some() {
1455+
return None;
14581456
}
1457+
1458+
return Some(infer.fully_canonicalize_goal(&inverted_subgoal));
14591459
}
14601460

14611461
/// Removes the subgoal at `subgoal_index` from the strand's

tests/test/cycle.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -164,7 +164,7 @@ fn overflow() {
164164
goal {
165165
S<Z>: Q
166166
} yields {
167-
"No possible solution"
167+
"Ambiguous; no inference guidance"
168168
}
169169
}
170170
}

tests/test/misc.rs

Lines changed: 17 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,8 @@ fn subgoal_abstraction() {
7272

7373
goal {
7474
exists<T> { T: Foo }
75-
} yields_all[SolverChoice::slg(50, None)] {
75+
} yields_first[SolverChoice::slg(50, None)] {
76+
"Floundered"
7677
}
7778
}
7879
}
@@ -169,25 +170,25 @@ fn subgoal_cycle_uninhabited() {
169170
impl<T> Foo for Box<T> where Box<Vec<T>>: Foo { }
170171
}
171172

172-
// There is no solution here with a finite proof, so we get
173-
// back: 0 answer(s) found.
173+
// Infinite recursion -> we flounder
174174
goal {
175175
exists<T> { T: Foo }
176-
} yields_all[SolverChoice::slg(2, None)] {
176+
} yields_first[SolverChoice::slg(2, None)] {
177+
"Floundered"
177178
}
178179

179-
// Unsurprisingly, applying negation succeeds then.
180+
// Unsurprisingly, applying negation also flounders.
180181
goal {
181182
not { exists<T> { T: Foo } }
182-
} yields_all[SolverChoice::slg(2, None)] {
183-
"substitution [], lifetime constraints []"
183+
} yields_first[SolverChoice::slg(2, None)] {
184+
"Floundered"
184185
}
185186

186187
// Equivalent to the previous.
187188
goal {
188189
forall<T> { not { T: Foo } }
189-
} yields_all[SolverChoice::slg(2, None)] {
190-
"substitution [], lifetime constraints []"
190+
} yields_first[SolverChoice::slg(2, None)] {
191+
"Floundered"
191192
}
192193

193194
// However, if we come across a negative goal that exceeds our
@@ -208,8 +209,9 @@ fn subgoal_cycle_uninhabited() {
208209
// Here, due to the hypothesis, there does indeed exist a suitable T, `U`.
209210
goal {
210211
forall<U> { if (U: Foo) { exists<T> { T: Foo } } }
211-
} yields_all[SolverChoice::slg(2, None)] {
212-
"substitution [?0 := !1_0], lifetime constraints []"
212+
} yields_first[SolverChoice::slg(2, None)] {
213+
"substitution [?0 := !1_0], lifetime constraints []",
214+
"Floundered"
213215
}
214216
}
215217
}
@@ -226,10 +228,12 @@ fn subgoal_cycle_inhabited() {
226228
impl Foo for u32 { }
227229
}
228230

231+
// Exceeds size threshold -> flounder
229232
goal {
230233
exists<T> { T: Foo }
231-
} yields_all[SolverChoice::slg(3, None)] {
232-
"substitution [?0 := u32], lifetime constraints []"
234+
} yields_first[SolverChoice::slg(3, None)] {
235+
"substitution [?0 := u32], lifetime constraints []",
236+
"Floundered"
233237
}
234238
}
235239
}

0 commit comments

Comments
 (0)