@@ -559,6 +559,19 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
559
559
} ;
560
560
if let AnswerMode :: Complete = self . forest . tables [ self . stack . top ( ) . table ] . answer_mode {
561
561
if ambiguous {
562
+ // FIXME: we could try to be a little bit smarter here. This can
563
+ // really be split into cases:
564
+ // 1) Cases where no amount of solving will cause this ambiguity to change.
565
+ // (e.g. `CannnotProve`)
566
+ // 2) Cases where we may be able to get a better answer if we
567
+ // solve other subgoals first.
568
+ // (e.g. the `non_enumerable_traits_reorder` test)
569
+ // We really only need to delay merging an ambiguous answer for
570
+ // case 2. Do note, though, that even if we *do* merge the answer
571
+ // case 1, we should stop solving this strand when in
572
+ // `AnswerMode::Complete` since we wouldn't use this answer yet
573
+ // *anyways*.
574
+
562
575
// The selected subgoal returned an ambiguous answer, but we don't want that.
563
576
// So, we treat this subgoal as floundered.
564
577
let selected_subgoal = strand. selected_subgoal . take ( ) . unwrap ( ) ;
@@ -568,23 +581,33 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
568
581
}
569
582
570
583
// If this subgoal was a `Positive` one, whichever way this
571
- // particular answer turns out, there may yet be *more* answers.
584
+ // particular answer turns out, there may yet be *more* answers,
585
+ // if this isn't a trivial substitution.
572
586
// Enqueue that alternative for later.
573
587
// NOTE: this is separate from the match below because we `take` the selected_subgoal
574
588
// below, but here we keep it for the new `Strand`.
575
589
let selected_subgoal = strand. selected_subgoal . as_ref ( ) . unwrap ( ) ;
576
590
if let Literal :: Positive ( _) = strand. ex_clause . subgoals [ selected_subgoal. subgoal_index ] {
577
- let mut next_subgoal = selected_subgoal. clone ( ) ;
578
- next_subgoal. answer_index . increment ( ) ;
579
- let next_strand = Strand {
580
- infer : strand. infer . clone ( ) ,
581
- ex_clause : strand. ex_clause . clone ( ) ,
582
- selected_subgoal : Some ( next_subgoal) ,
583
- last_pursued_time : strand. last_pursued_time . clone ( ) ,
584
- } ;
585
- let table = self . stack . top ( ) . table ;
586
- let canonical_next_strand = Forest :: canonicalize_strand ( self . context , next_strand) ;
587
- self . forest . tables [ table] . enqueue_strand ( canonical_next_strand) ;
591
+ let answer = self . forest . answer (
592
+ selected_subgoal. subgoal_table ,
593
+ selected_subgoal. answer_index ,
594
+ ) ;
595
+ if !self . context . is_trivial_substitution (
596
+ & self . forest . tables [ selected_subgoal. subgoal_table ] . table_goal ,
597
+ & answer. subst ,
598
+ ) {
599
+ let mut next_subgoal = selected_subgoal. clone ( ) ;
600
+ next_subgoal. answer_index . increment ( ) ;
601
+ let next_strand = Strand {
602
+ infer : strand. infer . clone ( ) ,
603
+ ex_clause : strand. ex_clause . clone ( ) ,
604
+ selected_subgoal : Some ( next_subgoal) ,
605
+ last_pursued_time : strand. last_pursued_time . clone ( ) ,
606
+ } ;
607
+ let table = self . stack . top ( ) . table ;
608
+ let canonical_next_strand = Forest :: canonicalize_strand ( self . context , next_strand) ;
609
+ self . forest . tables [ table] . enqueue_strand ( canonical_next_strand) ;
610
+ }
588
611
}
589
612
590
613
// Deselect and remove the selected subgoal, now that we have an answer for it.
@@ -1391,7 +1414,10 @@ impl<'forest, I: Interner, C: Context<I> + 'forest, CO: ContextOps<I, C> + 'fore
1391
1414
constraints,
1392
1415
filtered_delayed_subgoals,
1393
1416
) ;
1394
- debug ! ( "answer: table={:?}, subst={:?}, floundered={:?}" , table, subst, floundered) ;
1417
+ debug ! (
1418
+ "answer: table={:?}, subst={:?}, floundered={:?}" ,
1419
+ table, subst, floundered
1420
+ ) ;
1395
1421
1396
1422
let answer = Answer { subst, ambiguous } ;
1397
1423
0 commit comments