@@ -332,19 +332,61 @@ Type GenericSignatureImpl::getSuperclassBound(Type type) const {
332332 assert (type->isTypeParameter () &&
333333 " Only type parameters can have superclass requirements" );
334334
335- auto &builder = *getGenericSignatureBuilder ();
336- auto equivClass =
337- builder.resolveEquivalenceClass (
338- type,
339- ArchetypeResolutionKind::CompleteWellFormed);
340- if (!equivClass) return nullptr ;
335+ auto computeViaGSB = [&]() -> Type {
336+ auto &builder = *getGenericSignatureBuilder ();
337+ auto equivClass =
338+ builder.resolveEquivalenceClass (
339+ type,
340+ ArchetypeResolutionKind::CompleteWellFormed);
341+ if (!equivClass) return nullptr ;
342+
343+ // If this type was mapped to a concrete type, then there is no
344+ // requirement.
345+ if (equivClass->concreteType ) return nullptr ;
341346
342- // If this type was mapped to a concrete type, then there is no
343- // requirement.
344- if (equivClass->concreteType ) return nullptr ;
347+ // Retrieve the superclass bound.
348+ return equivClass->superclass ;
349+ };
350+
351+ auto computeViaRQM = [&]() {
352+ auto *machine = getRequirementMachine ();
353+ return machine->getSuperclassBound (type);
354+ };
355+
356+ auto &ctx = getASTContext ();
357+ if (ctx.LangOpts .EnableRequirementMachine ) {
358+ auto rqmResult = computeViaRQM ();
359+
360+ #ifndef NDEBUG
361+ auto gsbResult = computeViaGSB ();
345362
346- // Retrieve the superclass bound.
347- return equivClass->superclass ;
363+ auto check = [&]() {
364+ if (!gsbResult || !rqmResult)
365+ return !gsbResult == !rqmResult;
366+ return gsbResult->isEqual (rqmResult);
367+ };
368+
369+ if (!check ()) {
370+ llvm::errs () << " RequirementMachine::getSuperclassBound() is broken\n " ;
371+ llvm::errs () << " Generic signature: " << GenericSignature (this ) << " \n " ;
372+ llvm::errs () << " Dependent type: " ; type.dump (llvm::errs ());
373+ llvm::errs () << " GenericSignatureBuilder says: " << gsbResult << " \n " ;
374+ if (gsbResult)
375+ gsbResult.dump (llvm::errs ());
376+ llvm::errs () << " \n " ;
377+ llvm::errs () << " RequirementMachine says: " << rqmResult << " \n " ;
378+ if (rqmResult)
379+ rqmResult.dump (llvm::errs ());
380+ llvm::errs () << " \n " ;
381+ getRequirementMachine ()->dump (llvm::errs ());
382+ abort ();
383+ }
384+ #endif
385+
386+ return rqmResult;
387+ } else {
388+ return computeViaGSB ();
389+ }
348390}
349391
350392// / Determine the set of protocols to which the given type parameter is
@@ -516,14 +558,56 @@ bool GenericSignatureImpl::isConcreteType(Type type) const {
516558Type GenericSignatureImpl::getConcreteType (Type type) const {
517559 assert (type->isTypeParameter () && " Expected a type parameter" );
518560
519- auto &builder = *getGenericSignatureBuilder ();
520- auto equivClass =
561+ auto computeViaGSB = [&]() -> Type {
562+ auto &builder = *getGenericSignatureBuilder ();
563+ auto equivClass =
521564 builder.resolveEquivalenceClass (
522565 type,
523566 ArchetypeResolutionKind::CompleteWellFormed);
524- if (!equivClass) return Type () ;
567+ if (!equivClass) return nullptr ;
525568
526- return equivClass->concreteType ;
569+ return equivClass->concreteType ;
570+ };
571+
572+ auto computeViaRQM = [&]() {
573+ auto *machine = getRequirementMachine ();
574+ return machine->getConcreteType (type);
575+ };
576+
577+ auto &ctx = getASTContext ();
578+ if (ctx.LangOpts .EnableRequirementMachine ) {
579+ auto rqmResult = computeViaRQM ();
580+
581+ #ifndef NDEBUG
582+ auto gsbResult = computeViaGSB ();
583+
584+ auto check = [&]() {
585+ if (!gsbResult || !rqmResult)
586+ return !gsbResult == !rqmResult;
587+ return gsbResult->isEqual (rqmResult);
588+ };
589+
590+ if (!check ()) {
591+ llvm::errs () << " RequirementMachine::getConcreteType() is broken\n " ;
592+ llvm::errs () << " Generic signature: " << GenericSignature (this ) << " \n " ;
593+ llvm::errs () << " Dependent type: " ; type.dump (llvm::errs ());
594+ llvm::errs () << " GenericSignatureBuilder says: " << gsbResult << " \n " ;
595+ if (gsbResult)
596+ gsbResult.dump (llvm::errs ());
597+ llvm::errs () << " \n " ;
598+ llvm::errs () << " RequirementMachine says: " << rqmResult << " \n " ;
599+ if (rqmResult)
600+ rqmResult.dump (llvm::errs ());
601+ llvm::errs () << " \n " ;
602+ getRequirementMachine ()->dump (llvm::errs ());
603+ abort ();
604+ }
605+ #endif
606+
607+ return rqmResult;
608+ } else {
609+ return computeViaGSB ();
610+ }
527611}
528612
529613LayoutConstraint GenericSignatureImpl::getLayoutConstraint (Type type) const {
@@ -703,8 +787,39 @@ bool GenericSignatureImpl::isCanonicalTypeInContext(Type type) const {
703787 if (!type->hasTypeParameter ())
704788 return true ;
705789
706- auto &builder = *getGenericSignatureBuilder ();
707- return isCanonicalTypeInContext (type, builder);
790+ auto computeViaGSB = [&]() {
791+ auto &builder = *getGenericSignatureBuilder ();
792+ return isCanonicalTypeInContext (type, builder);
793+ };
794+
795+ auto computeViaRQM = [&]() {
796+ auto *machine = getRequirementMachine ();
797+ return machine->isCanonicalTypeInContext (type);
798+ };
799+
800+ auto &ctx = getASTContext ();
801+ if (ctx.LangOpts .EnableRequirementMachine ) {
802+ auto rqmResult = computeViaRQM ();
803+
804+ #ifndef NDEBUG
805+ auto gsbResult = computeViaGSB ();
806+
807+ if (gsbResult != rqmResult) {
808+ llvm::errs () << " RequirementMachine::isCanonicalTypeInContext() is broken\n " ;
809+ llvm::errs () << " Generic signature: " << GenericSignature (this ) << " \n " ;
810+ llvm::errs () << " Dependent type: " ; type.dump (llvm::errs ());
811+ llvm::errs () << " \n " ;
812+ llvm::errs () << " GenericSignatureBuilder says: " << gsbResult << " \n " ;
813+ llvm::errs () << " RequirementMachine says: " << rqmResult << " \n " ;
814+ getRequirementMachine ()->dump (llvm::errs ());
815+ abort ();
816+ }
817+ #endif
818+
819+ return rqmResult;
820+ } else {
821+ return computeViaGSB ();
822+ }
708823}
709824
710825bool GenericSignatureImpl::isCanonicalTypeInContext (
@@ -791,8 +906,117 @@ CanGenericSignature::getGenericParams() const{
791906ConformanceAccessPath
792907GenericSignatureImpl::getConformanceAccessPath (Type type,
793908 ProtocolDecl *protocol) const {
794- return getGenericSignatureBuilder ()->getConformanceAccessPath (
795- type, protocol, this );
909+ auto computeViaGSB = [&]() {
910+ return getGenericSignatureBuilder ()->getConformanceAccessPath (
911+ type, protocol, this );
912+ };
913+
914+ auto computeViaRQM = [&]() {
915+ auto *machine = getRequirementMachine ();
916+ return machine->getConformanceAccessPath (type, protocol);
917+ };
918+
919+ auto &ctx = getASTContext ();
920+ if (ctx.LangOpts .EnableRequirementMachine ) {
921+ auto rqmResult = computeViaRQM ();
922+
923+ #ifndef NDEBUG
924+ auto gsbResult = computeViaGSB ();
925+
926+ auto compare = [&]() {
927+ if (gsbResult.size () != rqmResult.size ())
928+ return false ;
929+
930+ auto *begin1 = gsbResult.begin ();
931+ auto *end1 = gsbResult.end ();
932+ auto *begin2 = rqmResult.begin ();
933+ auto *end2 = rqmResult.end ();
934+
935+ while (begin1 < end1) {
936+ assert (begin2 < end2);
937+
938+ if (!begin1->first ->isEqual (begin2->first ))
939+ return false ;
940+ if (begin1->second != begin2->second )
941+ return false ;
942+
943+ ++begin1;
944+ ++begin2;
945+ }
946+
947+ return true ;
948+ };
949+
950+ if (!compare ()) {
951+ llvm::errs () << " RequirementMachine::getConformanceAccessPath() is broken\n " ;
952+ llvm::errs () << " Generic signature: " << GenericSignature (this ) << " \n " ;
953+ llvm::errs () << " Dependent type: " ; type.dump (llvm::errs ());
954+ llvm::errs () << " Protocol: " ; protocol->dumpRef (llvm::errs ());
955+ llvm::errs () << " \n " ;
956+ llvm::errs () << " GenericSignatureBuilder says: " ;
957+ gsbResult.print (llvm::errs ());
958+ llvm::errs () << " \n " ;
959+ llvm::errs () << " RequirementMachine says: " ;
960+ rqmResult.print (llvm::errs ());
961+ llvm::errs () << " \n\n " ;
962+ getRequirementMachine ()->dump (llvm::errs ());
963+ abort ();
964+ }
965+ #endif
966+
967+ return rqmResult;
968+ } else {
969+ return computeViaGSB ();
970+ }
971+ }
972+
973+ TypeDecl *
974+ GenericSignatureImpl::lookupNestedType (Type type, Identifier name) const {
975+ assert (type->isTypeParameter ());
976+
977+ auto computeViaGSB = [&]() -> TypeDecl * {
978+ auto *builder = getGenericSignatureBuilder ();
979+ auto equivClass =
980+ builder->resolveEquivalenceClass (
981+ type,
982+ ArchetypeResolutionKind::CompleteWellFormed);
983+ if (!equivClass)
984+ return nullptr ;
985+
986+ return equivClass->lookupNestedType (*builder, name);
987+ };
988+
989+ auto computeViaRQM = [&]() {
990+ auto *machine = getRequirementMachine ();
991+ return machine->lookupNestedType (type, name);
992+ };
993+
994+ auto &ctx = getASTContext ();
995+ if (ctx.LangOpts .EnableRequirementMachine ) {
996+ auto rqmResult = computeViaRQM ();
997+
998+ #ifndef NDEBUG
999+ auto gsbResult = computeViaGSB ();
1000+
1001+ if (gsbResult != rqmResult) {
1002+ llvm::errs () << " RequirementMachine::lookupNestedType() is broken\n " ;
1003+ llvm::errs () << " Generic signature: " << GenericSignature (this ) << " \n " ;
1004+ llvm::errs () << " Dependent type: " ; type.dump (llvm::errs ());
1005+ llvm::errs () << " GenericSignatureBuilder says: " ;
1006+ gsbResult->dumpRef (llvm::errs ());
1007+ llvm::errs () << " \n " ;
1008+ llvm::errs () << " RequirementMachine says: " ;
1009+ rqmResult->dumpRef (llvm::errs ());
1010+ llvm::errs () << " \n " ;
1011+ getRequirementMachine ()->dump (llvm::errs ());
1012+ abort ();
1013+ }
1014+ #endif
1015+
1016+ return rqmResult;
1017+ } else {
1018+ return computeViaGSB ();
1019+ }
7961020}
7971021
7981022TypeDecl *
0 commit comments