@@ -743,12 +743,148 @@ void SolverTrail::undo(unsigned toIndex) {
743743void SolverTrail::dumpActiveScopeChanges (llvm::raw_ostream &out,
744744 unsigned fromIndex,
745745 unsigned indent) const {
746+ if (Changes.empty ())
747+ return ;
748+
749+ // Collect Changes for printing.
750+ std::vector<TypeVariableType *> addedTypeVars;
751+ std::set<TypeVariableType *> updatedTypeVars;
752+ std::set<Constraint *> addedConstraints;
753+ std::set<Constraint *> removedConstraints;
754+ for (unsigned int i = fromIndex; i < Changes.size (); i++) {
755+ auto change = Changes[i];
756+ switch (change.Kind ) {
757+ case ChangeKind::AddedTypeVariable:
758+ addedTypeVars.push_back (change.TypeVar );
759+ break ;
760+ case ChangeKind::UpdatedTypeVariable:
761+ updatedTypeVars.insert (change.Update .TypeVar );
762+ break ;
763+ case ChangeKind::AddedConstraint:
764+ addedConstraints.insert (change.TheConstraint .Constraint );
765+ break ;
766+ case ChangeKind::RemovedConstraint:
767+ removedConstraints.insert (change.TheConstraint .Constraint );
768+ break ;
769+ default :
770+ // Don't consider changes that don't affect the graph.
771+ break ;
772+ }
773+ }
774+
775+ // If there are any constraints that were both added and removed in this set
776+ // of Changes, remove them from both.
777+ std::set<Constraint *> intersects;
778+ set_intersection (addedConstraints.begin (), addedConstraints.end (),
779+ removedConstraints.begin (), removedConstraints.end (),
780+ std::inserter (intersects, intersects.begin ()));
781+ llvm::set_subtract (addedConstraints, intersects);
782+ llvm::set_subtract (removedConstraints, intersects);
783+
784+ // Print out Changes.
785+ PrintOptions PO;
786+ PO.PrintTypesForDebugging = true ;
746787 out.indent (indent);
747- out << " (changes:\n " ;
788+ out << " (Changes:\n " ;
789+ if (!addedTypeVars.empty ()) {
790+ out.indent (indent + 2 );
791+ auto heading = (addedTypeVars.size () > 1 ) ? " (New Type Variables: \n "
792+ : " (New Type Variable: \n " ;
793+ out << heading;
794+ for (const auto &typeVar : addedTypeVars) {
795+ out.indent (indent + 4 );
796+ out << " > $T" << typeVar->getImpl ().getID ();
797+ out << ' \n ' ;
798+ }
799+ out.indent (indent + 2 );
800+ out << " )\n " ;
801+ }
802+ if (!updatedTypeVars.empty ()) {
803+ std::vector<TypeVariableType *> assignments;
804+ std::vector<std::pair<TypeVariableType *, TypeVariableType *>> equivalences;
805+
806+ for (auto *typeVar : updatedTypeVars) {
807+ if (auto *parentVar =
808+ typeVar->getImpl ().getRepresentative (/* trail=*/ nullptr )) {
809+ if (parentVar != typeVar) {
810+ equivalences.push_back (std::make_pair (parentVar, typeVar));
811+ continue ;
812+ }
813+ }
814+
815+ if (typeVar->getImpl ().ParentOrFixed .is <TypeBase *>())
816+ assignments.push_back (typeVar);
817+ }
748818
749- for (unsigned i = fromIndex; i < Changes.size (); ++i)
750- Changes[i].dump (out, CS, indent + 2 );
819+ if (!assignments.empty ()) {
820+ out.indent (indent + 2 );
821+ auto heading = (assignments.size () > 1 ) ? " (Bound Type Variables: \n "
822+ : " (Bound Type Variable: \n " ;
823+ out << heading;
824+
825+ for (auto *typeVar : assignments) {
826+ out.indent (indent + 4 );
827+ out << " > $T" << typeVar->getImpl ().getID () << " := " ;
828+ typeVar->getImpl ().ParentOrFixed .get <TypeBase *>()->print (out, PO);
829+ out << ' \n ' ;
830+ }
831+ out.indent (indent + 2 );
832+ out << " )\n " ;
833+ }
834+
835+ if (!equivalences.empty ()) {
836+ out.indent (indent + 2 );
837+ auto heading = (equivalences.size () > 1 ) ? " (New Equivalences: \n "
838+ : " (New Equivalence: \n " ;
839+ out << heading;
840+ for (const auto &eq : equivalences) {
841+ out.indent (indent + 4 );
842+ out << " > $T" << eq.first ->getImpl ().getID ();
843+ out << " == " ;
844+ out << " $T" << eq.second ->getImpl ().getID ();
845+ out << ' \n ' ;
846+ }
847+ out.indent (indent + 2 );
848+ out << " )\n " ;
849+ }
850+ }
851+ if (!addedConstraints.empty ()) {
852+ out.indent (indent + 2 );
853+ auto heading = (addedConstraints.size () > 1 ) ? " (Added Constraints: \n "
854+ : " (Added Constraint: \n " ;
855+ out << heading;
856+ for (const auto &constraint : addedConstraints) {
857+ out.indent (indent + 4 );
858+ out << " > " ;
859+ constraint->print (out, &CS.getASTContext ().SourceMgr , indent + 6 );
860+ out << ' \n ' ;
861+ }
862+ out.indent (indent + 2 );
863+ out << " )\n " ;
864+ }
865+ if (!removedConstraints.empty ()) {
866+ out.indent (indent + 2 );
867+ auto heading = (removedConstraints.size () > 1 ) ? " (Removed Constraints: \n "
868+ : " (Removed Constraint: \n " ;
869+ out << heading;
870+ for (const auto &constraint : removedConstraints) {
871+ out.indent (indent + 4 );
872+ out << " > " ;
873+ constraint->print (out, &CS.getASTContext ().SourceMgr , indent + 6 );
874+ out << ' \n ' ;
875+ }
876+ out.indent (indent + 2 );
877+ out << " )\n " ;
878+ }
751879
752880 out.indent (indent);
753881 out << " )\n " ;
754882}
883+
884+ void SolverTrail::dump () const { dump (llvm::errs ()); }
885+
886+ void SolverTrail::dump (raw_ostream &OS, unsigned fromIndex,
887+ unsigned indent) const {
888+ for (unsigned i = fromIndex; i < Changes.size (); ++i)
889+ Changes[i].dump (OS, CS, indent);
890+ }
0 commit comments