@@ -849,11 +849,29 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
849
849
850
850
// There could be a local ambiguity related to
851
851
// the current element, let's try to resolve it.
852
- if (Solutions.size () > 1 ) {
852
+ if (Solutions.size () > 1 )
853
853
filterSolutions (Solutions, /* minimize=*/ true );
854
854
855
- if (Solutions.size () != 1 )
856
- return failConjunction ();
855
+ // In diagnostic mode we need to stop a conjunction
856
+ // but consider it successful if there are:
857
+ //
858
+ // - More than one solution for this element. Ambiguity
859
+ // needs to get propagated back to the outer context
860
+ // to be diagnosed.
861
+ // - A single solution that requires one or more fixes,
862
+ // continuing would result in more errors associated
863
+ // with the failed element.
864
+ if (CS.shouldAttemptFixes ()) {
865
+ if (Solutions.size () > 1 )
866
+ Producer.markExhausted ();
867
+
868
+ if (Solutions.size () == 1 ) {
869
+ auto score = Solutions.front ().getFixedScore ();
870
+ if (score.Data [SK_Fix] > 0 )
871
+ Producer.markExhausted ();
872
+ }
873
+ } else if (Solutions.size () != 1 ) {
874
+ return failConjunction ();
857
875
}
858
876
859
877
// Since there is only one solution, let's
@@ -889,6 +907,33 @@ StepResult ConjunctionStep::resume(bool prevFailed) {
889
907
Snapshot &&
890
908
" Isolated conjunction requires a snapshot of the constraint system" );
891
909
910
+ // In diagnostic mode it's valid for an element to have
911
+ // multiple solutions. Ambiguity just needs to be merged
912
+ // into the outer context to be property diagnosed.
913
+ if (Solutions.size () > 1 ) {
914
+ assert (CS.shouldAttemptFixes ());
915
+
916
+ // Restore all outer type variables, constraints
917
+ // and scoring information.
918
+ Snapshot.reset ();
919
+ restoreOuterState ();
920
+
921
+ // Apply all of the information deduced from the
922
+ // conjunction (up to the point of ambiguity)
923
+ // back to the outer context and form a joined solution.
924
+ for (auto &solution : Solutions) {
925
+ ConstraintSystem::SolverScope scope (CS);
926
+
927
+ CS.applySolution (solution);
928
+ // Note that `worseThanBestSolution` isn't checked
929
+ // here because `Solutions` were pre-filtered, and
930
+ // outer score is the same for all of them.
931
+ OuterSolutions.push_back (CS.finalize ());
932
+ }
933
+
934
+ return done (/* isSuccess=*/ true );
935
+ }
936
+
892
937
// Restore outer type variables and prepare to solve
893
938
// constraints associated with outer context together
894
939
// with information deduced from the conjunction.
0 commit comments