@@ -886,66 +886,64 @@ CheckGenericArgumentsResult TypeChecker::checkGenericArgumentsForDiagnostics(
886886 SmallVector<ParentConditionalConformance, 2 >;
887887
888888 struct WorklistItem {
889- // / The set of requirements to check. These are either the primary set
890- // / of requirements, or the conditional requirements of the last conformance
891- // / in \c ReqsPath (if any).
892- ArrayRef< Requirement> Requirements ;
889+ // / The requirement to check. This is either a top-level requirement or
890+ // / a conditional requirements of the last conformancein \c ReqsPath
891+ // / (if any).
892+ Requirement Req ;
893893
894894 // / The chain of conditional conformances that leads to the above
895895 // / requirement set.
896- ParentConditionalConformances ReqsPath ;
896+ ParentConditionalConformances Path ;
897897
898- WorklistItem (ArrayRef<Requirement> Requirements,
899- ParentConditionalConformances ReqsPath)
900- : Requirements(Requirements), ReqsPath(ReqsPath) {}
898+ WorklistItem (Requirement Req, ParentConditionalConformances Path)
899+ : Req(Req), Path(Path) {}
901900 };
902901
903902 bool hadSubstFailure = false ;
904903 SmallVector<WorklistItem, 4 > worklist;
905904
906- worklist.emplace_back (requirements, ParentConditionalConformances{});
905+ for (auto req : llvm::reverse (requirements))
906+ worklist.emplace_back (req, ParentConditionalConformances{});
907+
907908 while (!worklist.empty ()) {
908909 const auto item = worklist.pop_back_val ();
909910
910- const bool isPrimaryReq = item.ReqsPath .empty ();
911- for (const auto &req : item.Requirements ) {
912- Requirement substReq = req;
913- if (isPrimaryReq) {
914- // Primary requirements do not have substitutions applied.
915- auto resolved =
916- req.subst (substitutions, LookUpConformanceInModule (module ));
917- if (!resolved.hasError ()) {
918- substReq = resolved;
919- } else {
920- // Another requirement might fail later; just continue.
921- hadSubstFailure = true ;
922- continue ;
923- }
924- }
925-
926- ArrayRef<Requirement> conditionalRequirements;
927- if (!substReq.isSatisfied (conditionalRequirements,
928- /* allowMissing=*/ true )) {
929- return CheckGenericArgumentsResult::createRequirementFailure (
930- req, substReq, std::move (item.ReqsPath ));
931- }
911+ auto req = item.Req ;
912+ auto substReq = item.Req ;
913+ if (item.Path .empty ()) {
914+ // Primary requirements do not have substitutions applied.
915+ substReq =
916+ req.subst (substitutions, LookUpConformanceInModule (module ));
917+ }
932918
933- if (conditionalRequirements.empty ()) {
934- continue ;
935- }
919+ SmallVector<Requirement, 2 > subReqs;
920+ switch (substReq.checkRequirement (subReqs, /* allowMissing=*/ true )) {
921+ case CheckRequirementResult::Success:
922+ break ;
936923
937- assert (req.getKind () == RequirementKind::Conformance);
924+ case CheckRequirementResult::ConditionalConformance: {
925+ assert (substReq.getKind () == RequirementKind::Conformance);
938926
939- auto reqsPath = item.ReqsPath ;
927+ auto reqsPath = item.Path ;
940928 reqsPath.push_back ({substReq.getFirstType (), substReq.getProtocolDecl ()});
941929
942- worklist.emplace_back (conditionalRequirements, std::move (reqsPath));
930+ for (auto subReq : subReqs)
931+ worklist.emplace_back (subReq, reqsPath);
932+ break ;
933+ }
934+
935+ case CheckRequirementResult::RequirementFailure:
936+ return CheckGenericArgumentsResult::createRequirementFailure (
937+ req, substReq, std::move (item.Path ));
938+
939+ case CheckRequirementResult::SubstitutionFailure:
940+ hadSubstFailure = true ;
941+ break ;
943942 }
944943 }
945944
946- if (hadSubstFailure) {
945+ if (hadSubstFailure)
947946 return CheckGenericArgumentsResult::createSubstitutionFailure ();
948- }
949947
950948 return CheckGenericArgumentsResult::createSuccess ();
951949}
@@ -954,31 +952,34 @@ CheckGenericArgumentsResult::Kind TypeChecker::checkGenericArguments(
954952 ModuleDecl *module , ArrayRef<Requirement> requirements,
955953 TypeSubstitutionFn substitutions, SubstOptions options) {
956954 SmallVector<Requirement, 4 > worklist;
957- bool valid = true ;
955+
956+ bool hadSubstFailure = false ;
958957
959958 for (auto req : requirements) {
960- auto resolved = req.subst (substitutions,
961- LookUpConformanceInModule (module ), options);
962- if (!resolved.hasError ()) {
963- worklist.push_back (resolved);
964- } else {
965- valid = false ;
966- }
959+ worklist.push_back (req.subst (substitutions,
960+ LookUpConformanceInModule (module ), options));
967961 }
968962
969963 while (!worklist.empty ()) {
970964 auto req = worklist.pop_back_val ();
971- ArrayRef<Requirement> conditionalRequirements;
972- if (!req.isSatisfied (conditionalRequirements, /* allowMissing=*/ true ))
965+ switch (req.checkRequirement (worklist, /* allowMissing=*/ true )) {
966+ case CheckRequirementResult::Success:
967+ case CheckRequirementResult::ConditionalConformance:
968+ break ;
969+
970+ case CheckRequirementResult::RequirementFailure:
973971 return CheckGenericArgumentsResult::RequirementFailure;
974972
975- worklist.append (conditionalRequirements.begin (),
976- conditionalRequirements.end ());
973+ case CheckRequirementResult::SubstitutionFailure:
974+ hadSubstFailure = true ;
975+ break ;
976+ }
977977 }
978978
979- if (valid)
980- return CheckGenericArgumentsResult::Success;
981- return CheckGenericArgumentsResult::SubstitutionFailure;
979+ if (hadSubstFailure)
980+ return CheckGenericArgumentsResult::SubstitutionFailure;
981+
982+ return CheckGenericArgumentsResult::Success;
982983}
983984
984985Requirement
0 commit comments