Skip to content

Commit b9481dc

Browse files
committed
Cleanups
1 parent b0fc89a commit b9481dc

File tree

4 files changed

+60
-66
lines changed

4 files changed

+60
-66
lines changed

chalk-engine/src/lib.rs

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,6 @@ impl Minimums {
284284
}
285285
}
286286

287-
288287
#[derive(Copy, Clone, Debug)]
289288
pub(crate) enum AnswerMode {
290289
Complete,

chalk-engine/src/logic.rs

Lines changed: 54 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,8 @@ use crate::stack::{Stack, StackIndex};
66
use crate::strand::{CanonicalStrand, SelectedSubgoal, Strand};
77
use crate::table::{AnswerIndex, Table};
88
use crate::{
9-
Answer, AnswerMode, CompleteAnswer, ExClause, FlounderedSubgoal, Literal, Minimums, TableIndex, TimeStamp,
9+
Answer, AnswerMode, CompleteAnswer, ExClause, FlounderedSubgoal, Literal, Minimums, TableIndex,
10+
TimeStamp,
1011
};
1112
use chalk_base::results::{Floundered, NoSolution};
1213

@@ -22,7 +23,6 @@ type RootSearchResult<T> = Result<T, RootSearchFail>;
2223
/// many strands) can fail. A root search is one that begins with an
2324
/// empty stack.
2425
#[derive(Debug)]
25-
#[must_use]
2626
pub(super) enum RootSearchFail {
2727
/// The table we were trying to solve cannot succeed.
2828
NoMoreSolutions,
@@ -278,7 +278,10 @@ impl<I: Interner, C: Context<I>> Forest<I, C> {
278278
}
279279
}
280280
Err(Floundered) => {
281-
debug!("Marking table {:?} as floundered! (failed to create program clauses)", table_idx);
281+
debug!(
282+
"Marking table {:?} as floundered! (failed to create program clauses)",
283+
table_idx
284+
);
282285
table.mark_floundered();
283286
}
284287
}
@@ -491,8 +494,8 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
491494
selected_subgoal,
492495
last_pursued_time,
493496
} = canonical_strand;
494-
let (infer, ex_clause) = context
495-
.instantiate_ex_clause(num_universes, &canonical_ex_clause);
497+
let (infer, ex_clause) =
498+
context.instantiate_ex_clause(num_universes, &canonical_ex_clause);
496499
let strand = Strand {
497500
infer,
498501
ex_clause,
@@ -544,12 +547,14 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
544547
// the selected subgoal of the strand.
545548
// Now, we have to unify that answer onto the strand.
546549

547-
548550
// If this answer is ambiguous and we don't want ambiguous answers
549551
// yet, then we act like this is a floundered subgoal.
550552
let ambiguous = {
551553
let selected_subgoal = strand.selected_subgoal.as_ref().unwrap();
552-
let answer = self.forest.answer(selected_subgoal.subgoal_table, selected_subgoal.answer_index);
554+
let answer = self.forest.answer(
555+
selected_subgoal.subgoal_table,
556+
selected_subgoal.answer_index,
557+
);
553558
answer.ambiguous
554559
};
555560
if let AnswerMode::Complete = self.forest.tables[self.stack.top().table].answer_mode {
@@ -925,7 +930,7 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
925930
if let AnswerMode::Complete = self.forest.tables[self.stack.top().table].answer_mode {
926931
if ambiguous {
927932
// The strand can only return an ambiguous answer, but we don't
928-
// want that right noe, so requeue and we'll deal with it later.
933+
// want that right now, so requeue and we'll deal with it later.
929934
let canonical_strand = Forest::canonicalize_strand(self.context, strand);
930935
self.forest.tables[self.stack.top().table].enqueue_strand(canonical_strand);
931936
return NoRemainingSubgoalsResult::RootSearchFail(RootSearchFail::QuantumExceeded);
@@ -1061,7 +1066,10 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
10611066
loop {
10621067
// This table is marked as floundered
10631068
let table = self.stack.top().table;
1064-
debug!("Marking table {:?} as floundered! (all subgoals floundered)", table);
1069+
debug!(
1070+
"Marking table {:?} as floundered! (all subgoals floundered)",
1071+
table
1072+
);
10651073
self.forest.tables[table].mark_floundered();
10661074

10671075
let mut strand = match self.stack.pop_and_take_caller_strand() {
@@ -1148,41 +1156,46 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
11481156
let forest = &mut self.forest;
11491157
let context = &self.context;
11501158
let strand_is_participating = |strand: &CanonicalStrand<I>| {
1151-
let (_, ex_clause) = context
1152-
.instantiate_ex_clause(num_universes, &strand.canonical_ex_clause);
1159+
let (_, ex_clause) =
1160+
context.instantiate_ex_clause(num_universes, &strand.canonical_ex_clause);
11531161
match (table_answer_mode, ex_clause.ambiguous) {
11541162
(AnswerMode::Complete, true) => false,
11551163
(AnswerMode::Complete, false) => true,
11561164
(AnswerMode::Ambiguous, _) => true,
1157-
11581165
}
11591166
};
1160-
if forest.tables[table].strands_mut().any(|s| strand_is_participating(s)) {
1167+
// N.B. If we try to pursue a strand and it's found to be ambiguous,
1168+
// we know that isn't part of a cycle.
1169+
if forest.tables[table]
1170+
.strands_mut()
1171+
.any(|s| strand_is_participating(s))
1172+
{
11611173
let clock = self.stack.top().clock;
11621174
let cyclic_minimums = self.stack.top().cyclic_minimums;
11631175
if cyclic_minimums.positive >= clock && cyclic_minimums.negative >= clock {
11641176
debug!("cycle with no new answers");
1165-
1177+
11661178
if cyclic_minimums.negative < TimeStamp::MAX {
11671179
// This is a negative cycle.
11681180
self.unwind_stack();
11691181
return Err(RootSearchFail::NegativeCycle);
11701182
}
1171-
1183+
11721184
// If all the things that we recursively depend on have
11731185
// positive dependencies on things below us in the stack,
11741186
// then no more answers are forthcoming. We can clear all
11751187
// the strands for those things recursively.
11761188
let table = self.stack.top().table;
1177-
let cyclic_strands = self.forest.tables[table].drain_strands(strand_is_participating);
1189+
let cyclic_strands =
1190+
self.forest.tables[table].drain_strands(strand_is_participating);
11781191
self.clear_strands_after_cycle(cyclic_strands);
1179-
1192+
11801193
// Now we yield with `QuantumExceeded`
11811194
self.unwind_stack();
11821195
return Err(RootSearchFail::QuantumExceeded);
11831196
} else {
11841197
debug!("table part of a cycle");
1185-
1198+
11861199
// This table resulted in a positive cycle, so we have
11871200
// to check what this means for the subgoal containing
11881201
// this strand
@@ -1192,7 +1205,7 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
11921205
panic!("nothing on the stack but cyclic result");
11931206
}
11941207
};
1195-
1208+
11961209
// We can't take this because we might need it later to clear the cycle
11971210
let caller_selected_subgoal = caller_strand.selected_subgoal.as_ref().unwrap();
11981211
match caller_strand.ex_clause.subgoals[caller_selected_subgoal.subgoal_index] {
@@ -1215,13 +1228,14 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
12151228
self.stack.top().cyclic_minimums.take_minimums(&mins);
12161229
}
12171230
}
1218-
1231+
12191232
// We can't pursue this strand anymore, so push it back onto the table
12201233
let active_strand = self.stack.top().active_strand.take().unwrap();
12211234
let table = self.stack.top().table;
1222-
let canonical_active_strand = Forest::canonicalize_strand(self.context, active_strand);
1235+
let canonical_active_strand =
1236+
Forest::canonicalize_strand(self.context, active_strand);
12231237
self.forest.tables[table].enqueue_strand(canonical_active_strand);
1224-
1238+
12251239
// The strand isn't active, but the table is, so just continue
12261240
return Ok(());
12271241
}
@@ -1236,7 +1250,6 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
12361250
}
12371251
AnswerMode::Ambiguous => {
12381252
panic!();
1239-
12401253
}
12411254
}
12421255
}
@@ -1274,7 +1287,7 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
12741287
let selected_subgoal = selected_subgoal.unwrap_or_else(|| {
12751288
panic!(
12761289
"clear_strands_after_cycle invoked on strand in table \
1277-
without a selected subgoal: {:#?}",
1290+
without a selected subgoal: {:?}",
12781291
canonical_ex_clause,
12791292
)
12801293
});
@@ -1363,15 +1376,21 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
13631376
let table = self.stack.top().table;
13641377
let Strand {
13651378
mut infer,
1366-
ex_clause,
1379+
ex_clause:
1380+
ExClause {
1381+
subst,
1382+
constraints,
1383+
ambiguous,
1384+
subgoals,
1385+
delayed_subgoals,
1386+
answer_time: _,
1387+
floundered_subgoals,
1388+
},
13671389
selected_subgoal: _,
1368-
last_pursued_time,
1390+
last_pursued_time: _,
13691391
} = strand;
1370-
assert!(ex_clause.subgoals.is_empty());
1371-
let floundered = !ex_clause.floundered_subgoals.is_empty();
1372-
if floundered {
1373-
//return None;
1374-
}
1392+
assert!(subgoals.is_empty());
1393+
let floundered = !floundered_subgoals.is_empty();
13751394

13761395
// If the answer gets too large, mark the table as floundered.
13771396
// This is the *most conservative* course. There are a few alternatives:
@@ -1390,36 +1409,11 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
13901409
// Ultimately, the current decision to flounder the entire table mostly boils
13911410
// down to "it works as we expect for the current tests". And, we likely don't
13921411
// even *need* the added complexity just for potentially more answers.
1393-
if infer.answer_needs_truncation(self.context.interner(), &ex_clause.subst) {
1412+
if infer.answer_needs_truncation(self.context.interner(), &subst) {
13941413
self.forest.tables[table].mark_floundered();
13951414
return None;
13961415
}
13971416

1398-
if ex_clause.ambiguous || floundered {
1399-
let table = &mut self.forest.tables[table];
1400-
if let AnswerMode::Complete = table.answer_mode {
1401-
let canonical_strand = Forest::canonicalize_strand_from(
1402-
self.context,
1403-
&mut infer,
1404-
&ex_clause,
1405-
None,
1406-
last_pursued_time,
1407-
);
1408-
table.enqueue_strand(canonical_strand);
1409-
return None;
1410-
}
1411-
}
1412-
1413-
let ExClause {
1414-
subst,
1415-
constraints,
1416-
ambiguous,
1417-
subgoals: _,
1418-
delayed_subgoals,
1419-
answer_time: _,
1420-
floundered_subgoals: _,
1421-
} = ex_clause;
1422-
14231417
let table_goal = &self.forest.tables[table].table_goal;
14241418

14251419
// FIXME: Avoid double canonicalization
@@ -1447,7 +1441,7 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
14471441
debug!("answer: table={:?}, subst={:?}", table, subst);
14481442
}
14491443

1450-
let answer = Answer { subst, ambiguous: ambiguous || floundered };
1444+
let answer = Answer { subst, ambiguous };
14511445

14521446
// A "trivial" answer is one that is 'just true for all cases'
14531447
// -- in other words, it gives no information back to the
@@ -1508,10 +1502,9 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
15081502
// is a *bit* suspect; e.g., those things in the environment
15091503
// must be backed by an impl *eventually*).
15101504
let is_trivial_answer = {
1511-
self
1512-
.context
1505+
self.context
15131506
.is_trivial_substitution(&self.forest.tables[table].table_goal, &answer.subst)
1514-
&& answer.subst.value.constraints.is_empty()
1507+
&& answer.subst.value.constraints.is_empty()
15151508
};
15161509

15171510
if let Some(answer_index) = self.forest.tables[table].push_answer(answer) {

chalk-engine/src/table.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,14 +85,16 @@ impl<I: Interner> Table<I> {
8585

8686
pub(crate) fn drain_strands(
8787
&mut self,
88-
test: impl Fn(&CanonicalStrand<I>) -> bool
88+
test: impl Fn(&CanonicalStrand<I>) -> bool,
8989
) -> VecDeque<CanonicalStrand<I>> {
9090
let old = mem::replace(&mut self.strands, VecDeque::new());
91-
let (test_in, test_out): (VecDeque<CanonicalStrand<I>>, VecDeque<CanonicalStrand<I>>) = old.into_iter().partition(test);
91+
let (test_in, test_out): (VecDeque<CanonicalStrand<I>>, VecDeque<CanonicalStrand<I>>) =
92+
old.into_iter().partition(test);
9293
let _ = mem::replace(&mut self.strands, test_out);
9394
test_in
9495
}
9596

97+
/// Remove the next strand from the queue that meets the given criteria
9698
pub(crate) fn dequeue_next_strand_that(
9799
&mut self,
98100
test: impl Fn(&CanonicalStrand<I>) -> bool,

tests/test/projection.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,9 @@ fn iterator_flatten() {
368368
} yields[SolverChoice::slg_default()] {
369369
// this is wrong, chalk#234
370370
"Ambiguous"
371-
}/* yields[SolverChoice::recursive()] {
371+
} yields[SolverChoice::recursive()] {
372372
"Unique; substitution [?0 := Uint(U32)]"
373-
}*/
373+
}
374374
}
375375
}
376376

0 commit comments

Comments
 (0)