@@ -76,45 +76,99 @@ ProtocolDecl *Requirement::getProtocolDecl() const {
7676 return getSecondType ()->castTo <ProtocolType>()->getDecl ();
7777}
7878
79- bool
80- Requirement::isSatisfied (ArrayRef<Requirement> &conditionalRequirements,
81- bool allowMissing) const {
79+ CheckRequirementResult Requirement::checkRequirement (
80+ SmallVectorImpl<Requirement> &subReqs,
81+ bool allowMissing) const {
82+ if (hasError ())
83+ return CheckRequirementResult::SubstitutionFailure;
84+
85+ auto firstType = getFirstType ();
86+
87+ auto expandPackRequirement = [&](PackType *packType) {
88+ for (auto eltType : packType->getElementTypes ()) {
89+ // FIXME: Doesn't seem right
90+ if (auto *expansionType = eltType->getAs <PackExpansionType>())
91+ eltType = expansionType->getPatternType ();
92+
93+ auto kind = getKind ();
94+ if (kind == RequirementKind::Layout) {
95+ subReqs.emplace_back (kind, eltType,
96+ getLayoutConstraint ());
97+ } else {
98+ subReqs.emplace_back (kind, eltType,
99+ getSecondType ());
100+ }
101+ }
102+ return CheckRequirementResult::PackRequirement;
103+ };
104+
82105 switch (getKind ()) {
83106 case RequirementKind::Conformance: {
107+ if (auto packType = firstType->getAs <PackType>()) {
108+ return expandPackRequirement (packType);
109+ }
110+
84111 auto *proto = getProtocolDecl ();
85112 auto *module = proto->getParentModule ();
86113 auto conformance = module ->lookupConformance (
87- getFirstType () , proto, allowMissing);
114+ firstType , proto, allowMissing);
88115 if (!conformance)
89- return false ;
116+ return CheckRequirementResult::RequirementFailure ;
90117
91- conditionalRequirements = conformance.getConditionalRequirements ();
92- return true ;
118+ auto condReqs = conformance.getConditionalRequirements ();
119+ if (condReqs.empty ())
120+ return CheckRequirementResult::Success;
121+ subReqs.append (condReqs.begin (), condReqs.end ());
122+ return CheckRequirementResult::ConditionalConformance;
93123 }
94124
95125 case RequirementKind::Layout: {
96- if (auto *archetypeType = getFirstType ()->getAs <ArchetypeType>()) {
126+ if (auto packType = firstType->getAs <PackType>()) {
127+ return expandPackRequirement (packType);
128+ }
129+
130+ if (auto *archetypeType = firstType->getAs <ArchetypeType>()) {
97131 auto layout = archetypeType->getLayoutConstraint ();
98- return (layout && layout.merge (getLayoutConstraint ()));
132+ if (layout && layout.merge (getLayoutConstraint ()))
133+ return CheckRequirementResult::Success;
134+
135+ return CheckRequirementResult::RequirementFailure;
99136 }
100137
101- if (getLayoutConstraint ()->isClass ())
102- return getFirstType ()->satisfiesClassConstraint ();
138+ if (getLayoutConstraint ()->isClass ()) {
139+ if (firstType->satisfiesClassConstraint ())
140+ return CheckRequirementResult::Success;
141+
142+ return CheckRequirementResult::RequirementFailure;
143+ }
103144
104145 // TODO: Statically check other layout constraints, once they can
105146 // be spelled in Swift.
106- return true ;
147+ return CheckRequirementResult::Success ;
107148 }
108149
109150 case RequirementKind::Superclass:
110- return getSecondType ()->isExactSuperclassOf (getFirstType ());
151+ if (auto packType = firstType->getAs <PackType>()) {
152+ return expandPackRequirement (packType);
153+ }
154+
155+ if (getSecondType ()->isExactSuperclassOf (firstType))
156+ return CheckRequirementResult::Success;
157+
158+ return CheckRequirementResult::RequirementFailure;
111159
112160 case RequirementKind::SameType:
113- return getFirstType ()->isEqual (getSecondType ());
161+ if (firstType->isEqual (getSecondType ()))
162+ return CheckRequirementResult::Success;
163+
164+ return CheckRequirementResult::RequirementFailure;
114165
115166 case RequirementKind::SameShape:
116- return (getFirstType ()->getReducedShape () ==
117- getSecondType ()->getReducedShape ());
167+ if (firstType->getReducedShape () ==
168+ getSecondType ()->getReducedShape ())
169+ return CheckRequirementResult::Success;
170+
171+ return CheckRequirementResult::RequirementFailure;
118172 }
119173
120174 llvm_unreachable (" Bad requirement kind" );
0 commit comments