Skip to content

Commit 5882254

Browse files
committed
RequirementMachine: Use Requirement::checkRequirement() to desugar conformance requirements
1 parent e14ac9e commit 5882254

File tree

2 files changed

+39
-51
lines changed

2 files changed

+39
-51
lines changed

lib/AST/RequirementMachine/RequirementLowering.cpp

Lines changed: 35 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -281,66 +281,54 @@ static void desugarConformanceRequirement(Requirement req,
281281
SourceLoc loc,
282282
SmallVectorImpl<Requirement> &result,
283283
SmallVectorImpl<RequirementError> &errors) {
284+
SmallVector<Requirement, 2> subReqs;
285+
286+
auto constraintType = req.getSecondType();
287+
284288
// Fast path.
285-
if (req.getSecondType()->is<ProtocolType>()) {
289+
if (constraintType->is<ProtocolType>()) {
286290
if (req.getFirstType()->isTypeParameter()) {
287291
result.push_back(req);
288292
return;
289293
}
290294

291295
// Check if the subject type actually conforms.
292-
auto *protoDecl = req.getProtocolDecl();
293-
auto *module = protoDecl->getParentModule();
294-
auto conformance = module->lookupConformance(
295-
req.getFirstType(), protoDecl, /*allowMissing=*/true);
296-
if (conformance.isInvalid()) {
296+
switch (req.checkRequirement(subReqs, /*allowMissing=*/true)) {
297+
case CheckRequirementResult::Success:
298+
case CheckRequirementResult::PackRequirement:
299+
case CheckRequirementResult::ConditionalConformance:
300+
errors.push_back(RequirementError::forRedundantRequirement(req, loc));
301+
break;
302+
303+
case CheckRequirementResult::RequirementFailure:
297304
errors.push_back(RequirementError::forInvalidRequirementSubject(req, loc));
298-
return;
299-
}
300-
301-
errors.push_back(RequirementError::forRedundantRequirement(req, loc));
305+
break;
302306

303-
if (conformance.isConcrete()) {
304-
// Introduce conditional requirements if the conformance is concrete.
305-
for (auto condReq : conformance.getConcrete()->getConditionalRequirements()) {
306-
desugarRequirement(condReq, loc, result, errors);
307-
}
307+
case CheckRequirementResult::SubstitutionFailure:
308+
break;
309+
}
310+
} else if (auto *paramType = constraintType->getAs<ParameterizedProtocolType>()) {
311+
subReqs.emplace_back(RequirementKind::Conformance, req.getFirstType(),
312+
paramType->getBaseType());
313+
paramType->getRequirements(req.getFirstType(), subReqs);
314+
} else if (auto *compositionType = constraintType->castTo<ProtocolCompositionType>()) {
315+
if (compositionType->hasExplicitAnyObject()) {
316+
subReqs.emplace_back(RequirementKind::Layout, req.getFirstType(),
317+
LayoutConstraint::getLayoutConstraint(
318+
LayoutConstraintKind::Class));
308319
}
309320

310-
return;
311-
}
312-
313-
if (auto *paramType = req.getSecondType()->getAs<ParameterizedProtocolType>()) {
314-
SmallVector<Requirement, 2> reqs;
315-
316-
reqs.emplace_back(RequirementKind::Conformance, req.getFirstType(),
317-
paramType->getBaseType());
318-
paramType->getRequirements(req.getFirstType(), reqs);
319-
320-
for (const auto &req : reqs)
321-
desugarRequirement(req, loc, result, errors);
322-
323-
return;
324-
}
325-
326-
auto *compositionType = req.getSecondType()->castTo<ProtocolCompositionType>();
327-
SmallVector<Requirement, 2> memberReqs;
328-
if (compositionType->hasExplicitAnyObject()) {
329-
memberReqs.emplace_back(RequirementKind::Layout, req.getFirstType(),
330-
LayoutConstraint::getLayoutConstraint(
331-
LayoutConstraintKind::Class));
332-
}
333-
334-
for (auto memberType : compositionType->getMembers()) {
335-
memberReqs.emplace_back(
336-
memberType->isConstraintType()
337-
? RequirementKind::Conformance
338-
: RequirementKind::Superclass,
339-
req.getFirstType(), memberType);
321+
for (auto memberType : compositionType->getMembers()) {
322+
subReqs.emplace_back(
323+
memberType->isConstraintType()
324+
? RequirementKind::Conformance
325+
: RequirementKind::Superclass,
326+
req.getFirstType(), memberType);
327+
}
340328
}
341329

342-
for (auto memberReq : memberReqs)
343-
desugarRequirement(memberReq, loc, result, errors);
330+
for (auto subReq : subReqs)
331+
desugarRequirement(subReq, loc, result, errors);
344332
}
345333

346334
/// Desugar same-shape requirements by equating the shapes of the

test/decl/protocol/conforms/variadic_generic_type.swift

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,18 +15,18 @@ struct HasPack<each A>: HasAssoc {}
1515
protocol P {}
1616

1717
protocol HasPackRequirements {
18-
func doStuff1<each U>(_ value: repeat each U) -> (repeat Array<each U>)
19-
func doStuff2<each U>(_ value: repeat each U) -> (repeat Array<each U>)
18+
func doStuff1<each U: P>(_ value: repeat each U) -> (repeat Array<each U>)
19+
func doStuff2<each U: P>(_ value: repeat each U) -> (repeat Array<each U>)
2020
}
2121

2222
extension HasPackRequirements {
23-
func doStuff1<each U>(_ value: repeat each U) -> (repeat Array<each U>) {
23+
func doStuff1<each U: P>(_ value: repeat each U) -> (repeat Array<each U>) {
2424
return (repeat [each value])
2525
}
2626
}
2727

2828
struct ConformsPackRequirements<each T>: HasPackRequirements {
29-
func doStuff2<each U>(_ value: repeat each U) -> (repeat Array<each U>) {
29+
func doStuff2<each U: P>(_ value: repeat each U) -> (repeat Array<each U>) {
3030
return (repeat [each value])
3131
}
3232
}

0 commit comments

Comments
 (0)