Skip to content

Commit 6cb64c4

Browse files
committed
AST: Refactor GenericSignature::isRequirementSatisfied() to use Requirement::isSatisfied()
This becomes a utility that maps the requirement's types into the generic environment if needed before calling out to the new Requirement::isSatisfied().
1 parent fe06df8 commit 6cb64c4

File tree

1 file changed

+16
-50
lines changed

1 file changed

+16
-50
lines changed

lib/AST/GenericSignature.cpp

Lines changed: 16 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -428,62 +428,28 @@ bool GenericSignatureImpl::areSameTypeParameterInContext(Type type1,
428428

429429
bool GenericSignatureImpl::isRequirementSatisfied(
430430
Requirement requirement) const {
431-
auto GSB = getGenericSignatureBuilder();
431+
if (requirement.getFirstType()->hasTypeParameter()) {
432+
auto *genericEnv = getGenericEnvironment();
432433

433-
auto firstType = requirement.getFirstType();
434-
auto canFirstType = getCanonicalTypeInContext(firstType);
434+
auto substituted = requirement.subst(
435+
[&](SubstitutableType *type) -> Type {
436+
if (auto *paramType = type->getAs<GenericTypeParamType>())
437+
return genericEnv->mapTypeIntoContext(paramType);
435438

436-
switch (requirement.getKind()) {
437-
case RequirementKind::Conformance: {
438-
auto *protocol = requirement.getProtocolDecl();
439+
return type;
440+
},
441+
LookUpConformanceInSignature(this));
439442

440-
if (canFirstType->isTypeParameter())
441-
return requiresProtocol(canFirstType, protocol);
442-
else
443-
return (bool)GSB->lookupConformance(canFirstType, protocol);
444-
}
443+
if (!substituted)
444+
return false;
445445

446-
case RequirementKind::SameType: {
447-
auto canSecondType = getCanonicalTypeInContext(requirement.getSecondType());
448-
return canFirstType->isEqual(canSecondType);
446+
requirement = *substituted;
449447
}
450448

451-
case RequirementKind::Superclass: {
452-
auto requiredSuperclass =
453-
getCanonicalTypeInContext(requirement.getSecondType());
454-
455-
// The requirement could be in terms of type parameters like a user-written
456-
// requirement, but it could also be in terms of concrete types if it has
457-
// been substituted/otherwise 'resolved', so we need to handle both.
458-
auto baseType = canFirstType;
459-
if (baseType->isTypeParameter()) {
460-
auto directSuperclass = getSuperclassBound(baseType);
461-
if (!directSuperclass)
462-
return false;
463-
464-
baseType = getCanonicalTypeInContext(directSuperclass);
465-
}
466-
467-
return requiredSuperclass->isExactSuperclassOf(baseType);
468-
}
449+
// FIXME: Need to check conditional requirements here.
450+
ArrayRef<Requirement> conditionalRequirements;
469451

470-
case RequirementKind::Layout: {
471-
auto requiredLayout = requirement.getLayoutConstraint();
472-
473-
if (canFirstType->isTypeParameter()) {
474-
if (auto layout = getLayoutConstraint(canFirstType))
475-
return static_cast<bool>(layout.merge(requiredLayout));
476-
477-
return false;
478-
}
479-
480-
// The requirement is on a concrete type, so it's either globally correct
481-
// or globally incorrect, independent of this generic context. The latter
482-
// case should be diagnosed elsewhere, so let's assume it's correct.
483-
return true;
484-
}
485-
}
486-
llvm_unreachable("unhandled kind");
452+
return requirement.isSatisfied(conditionalRequirements);
487453
}
488454

489455
SmallVector<Requirement, 4> GenericSignatureImpl::requirementsNotSatisfiedBy(
@@ -494,7 +460,7 @@ SmallVector<Requirement, 4> GenericSignatureImpl::requirementsNotSatisfiedBy(
494460
if (otherSig.getPointer() == this) return result;
495461

496462
// If there is no other signature, no requirements are satisfied.
497-
if (!otherSig){
463+
if (!otherSig) {
498464
const auto reqs = getRequirements();
499465
result.append(reqs.begin(), reqs.end());
500466
return result;

0 commit comments

Comments
 (0)