@@ -678,6 +678,69 @@ static const RequirementEnvironment &getOrCreateRequirementEnvironment(
678
678
return cacheIter->getSecond ();
679
679
}
680
680
681
+ static Optional<RequirementMatch> findMissingGenericRequirementForSolutionFix (
682
+ constraints::ConstraintFix *fix, ValueDecl *witness,
683
+ ProtocolConformance *conformance,
684
+ const RequirementEnvironment &reqEnvironment) {
685
+ Type type, missingType;
686
+ RequirementKind requirementKind;
687
+
688
+ using namespace constraints ;
689
+
690
+ switch (fix->getKind ()) {
691
+ case FixKind::AddConformance: {
692
+ auto missingConform = (MissingConformance *)fix;
693
+ requirementKind = RequirementKind::Conformance;
694
+ type = missingConform->getNonConformingType ();
695
+ missingType = missingConform->getProtocol ()->getDeclaredType ();
696
+ break ;
697
+ }
698
+ case FixKind::SkipSameTypeRequirement: {
699
+ requirementKind = RequirementKind::SameType;
700
+ auto requirementFix = (SkipSameTypeRequirement *)fix;
701
+ type = requirementFix->lhsType ();
702
+ missingType = requirementFix->rhsType ();
703
+ break ;
704
+ }
705
+ case FixKind::SkipSuperclassRequirement: {
706
+ requirementKind = RequirementKind::Superclass;
707
+ auto requirementFix = (SkipSuperclassRequirement *)fix;
708
+ type = requirementFix->subclassType ();
709
+ missingType = requirementFix->superclassType ();
710
+ break ;
711
+ }
712
+ default :
713
+ return Optional<RequirementMatch>();
714
+ }
715
+
716
+ auto missingRequirementMatch = [&](Type type) -> RequirementMatch {
717
+ Requirement requirement (requirementKind, type, missingType);
718
+ return RequirementMatch (witness, MatchKind::MissingRequirement,
719
+ requirement);
720
+ };
721
+
722
+ if (auto memberTy = type->getAs <DependentMemberType>())
723
+ return missingRequirementMatch (type);
724
+
725
+ type = type->mapTypeOutOfContext ();
726
+ if (type->hasTypeParameter ())
727
+ if (auto env = conformance->getGenericEnvironment ())
728
+ if (auto assocType = env->mapTypeIntoContext (type))
729
+ return missingRequirementMatch (assocType);
730
+
731
+ auto reqSubMap = reqEnvironment.getRequirementToSyntheticMap ();
732
+ auto proto = conformance->getProtocol ();
733
+ Type selfTy = proto->getSelfInterfaceType ().subst (reqSubMap);
734
+ if (type->isEqual (selfTy)) {
735
+ type = conformance->getType ();
736
+ if (auto agt = type->getAs <AnyGenericType>())
737
+ type = agt->getDecl ()->getDeclaredInterfaceType ();
738
+ return missingRequirementMatch (type);
739
+ }
740
+
741
+ return Optional<RequirementMatch>();
742
+ }
743
+
681
744
RequirementMatch
682
745
swift::matchWitness (TypeChecker &tc,
683
746
WitnessChecker::RequirementEnvironmentCache &reqEnvCache,
@@ -845,61 +908,13 @@ swift::matchWitness(TypeChecker &tc,
845
908
846
909
// If the types would match but for some other missing conformance, find and
847
910
// call that out.
848
- if (solution && conformance && solution->Fixes .size () == 1 ) {
849
- auto fix = solution->Fixes .front ();
850
- Type type, missingType;
851
- RequirementKind requirementKind;
852
- switch (fix->getKind ()) {
853
- case FixKind::AddConformance: {
854
- auto missingConform = (MissingConformance *)fix;
855
- requirementKind = RequirementKind::Conformance;
856
- type = missingConform->getNonConformingType ();
857
- missingType = missingConform->getProtocol ()->getDeclaredType ();
858
- break ;
859
- }
860
- case FixKind::SkipSameTypeRequirement: {
861
- requirementKind = RequirementKind::SameType;
862
- auto requirementFix = (SkipSameTypeRequirement *)fix;
863
- type = requirementFix->lhsType ();
864
- missingType = requirementFix->rhsType ();
865
- break ;
866
- }
867
- case FixKind::SkipSuperclassRequirement: {
868
- requirementKind = RequirementKind::Superclass;
869
- auto requirementFix = (SkipSuperclassRequirement *)fix;
870
- type = requirementFix->subclassType ();
871
- missingType = requirementFix->superclassType ();
872
- break ;
873
- }
874
- default :
875
- return RequirementMatch (witness, MatchKind::TypeConflict, witnessType);
876
- }
877
-
878
- auto missingRequirementMatch = [&](Type type) -> RequirementMatch {
879
- Requirement requirement (requirementKind, type, missingType);
880
- return RequirementMatch (witness, MatchKind::MissingRequirement,
881
- requirement);
882
- };
883
-
884
- if (auto memberTy = type->getAs <DependentMemberType>())
885
- return missingRequirementMatch (type);
886
-
887
- type = type->mapTypeOutOfContext ();
888
- if (type->hasTypeParameter ())
889
- if (auto env = conformance->getGenericEnvironment ())
890
- if (auto assocType = env->mapTypeIntoContext (type))
891
- return missingRequirementMatch (assocType);
892
-
893
- auto reqSubMap = reqEnvironment.getRequirementToSyntheticMap ();
894
- Type selfTy = proto->getSelfInterfaceType ().subst (reqSubMap);
895
- if (type->isEqual (selfTy)) {
896
- type = conformance->getType ();
897
- if (auto agt = type->getAs <AnyGenericType>())
898
- type = agt->getDecl ()->getDeclaredInterfaceType ();
899
- return missingRequirementMatch (type);
911
+ if (solution && conformance && solution->Fixes .size ()) {
912
+ for (auto fix : solution->Fixes ) {
913
+ if (auto result = findMissingGenericRequirementForSolutionFix (
914
+ fix, witness, conformance, reqEnvironment))
915
+ return *result;
900
916
}
901
917
}
902
-
903
918
if (!solution || solution->Fixes .size ())
904
919
return RequirementMatch (witness, MatchKind::TypeConflict,
905
920
witnessType);
0 commit comments