Skip to content

Commit 1bc4a4f

Browse files
committed
GSB: Refactor enumerateRequirements() a bit
Extract out createRequirement(), since I'm going to be using it soon. Also, merge the two loops together to do a single walk over all the equivalence classes, instead of pointlessly building a list of SameTypeComponentRefs first.
1 parent b921c8c commit 1bc4a4f

File tree

1 file changed

+122
-125
lines changed

1 file changed

+122
-125
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 122 additions & 125 deletions
Original file line numberDiff line numberDiff line change
@@ -8013,161 +8013,158 @@ namespace {
80138013

80148014
return false;
80158015
}
8016+
} // end anonymous namespace
8017+
8018+
static Optional<Requirement> createRequirement(RequirementKind kind,
8019+
Type depTy,
8020+
RequirementRHS rhs,
8021+
TypeArrayView<GenericTypeParamType> genericParams) {
80168022

8017-
using SameTypeComponentRef = std::pair<EquivalenceClass *, unsigned>;
8023+
depTy = getSugaredDependentType(depTy, genericParams);
80188024

8019-
} // end anonymous namespace
8025+
if (auto type = rhs.dyn_cast<Type>()) {
8026+
if (type->hasError())
8027+
return None;
8028+
8029+
// Drop requirements involving concrete types containing
8030+
// unresolved associated types.
8031+
if (type->findUnresolvedDependentMemberType())
8032+
return None;
8033+
8034+
if (type->isTypeParameter())
8035+
type = getSugaredDependentType(type, genericParams);
8036+
8037+
return Requirement(kind, depTy, type);
8038+
} else if (auto *proto = rhs.dyn_cast<ProtocolDecl *>()) {
8039+
auto type = proto->getDeclaredInterfaceType();
8040+
return Requirement(kind, depTy, type);
8041+
} else {
8042+
auto layoutConstraint = rhs.get<LayoutConstraint>();
8043+
return Requirement(kind, depTy, layoutConstraint);
8044+
}
8045+
}
80208046

80218047
void GenericSignatureBuilder::enumerateRequirements(
80228048
TypeArrayView<GenericTypeParamType> genericParams,
80238049
SmallVectorImpl<Requirement> &requirements) {
80248050
auto recordRequirement = [&](RequirementKind kind,
80258051
Type depTy,
80268052
RequirementRHS rhs) {
8027-
depTy = getSugaredDependentType(depTy, genericParams);
8028-
8029-
if (auto type = rhs.dyn_cast<Type>()) {
8030-
if (type->hasError())
8031-
return;
8032-
8033-
// Drop requirements involving concrete types containing
8034-
// unresolved associated types.
8035-
if (type->findUnresolvedDependentMemberType()) {
8036-
assert(Impl->HadAnyError);
8037-
return;
8038-
}
8039-
8040-
if (type->isTypeParameter())
8041-
type = getSugaredDependentType(type, genericParams);
8042-
8043-
requirements.push_back(Requirement(kind, depTy, type));
8044-
} else if (auto *proto = rhs.dyn_cast<ProtocolDecl *>()) {
8045-
auto type = proto->getDeclaredInterfaceType();
8046-
requirements.push_back(Requirement(kind, depTy, type));
8047-
} else {
8048-
auto layoutConstraint = rhs.get<LayoutConstraint>();
8049-
requirements.push_back(Requirement(kind, depTy, layoutConstraint));
8050-
return;
8051-
}
8053+
if (auto req = createRequirement(kind, depTy, rhs, genericParams))
8054+
requirements.push_back(*req);
80528055
};
80538056

80548057
// Collect all of the subject types that will be involved in constraints.
8055-
SmallVector<SameTypeComponentRef, 8> subjects;
80568058
for (auto &equivClass : Impl->EquivalenceClasses) {
80578059
if (equivClass.derivedSameTypeComponents.empty()) {
8058-
checkSameTypeConstraints(getGenericParams(), &equivClass);
8059-
}
8060-
8061-
for (unsigned i : indices(equivClass.derivedSameTypeComponents))
8062-
subjects.push_back({&equivClass, i});
8063-
}
8064-
8065-
for (const auto &subject : subjects) {
8066-
// Dig out the subject type and its corresponding component.
8067-
auto equivClass = subject.first;
8068-
auto &component = equivClass->derivedSameTypeComponents[subject.second];
8069-
Type subjectType = component.type;
8070-
8071-
assert(!subjectType->hasError());
8072-
assert(!subjectType->findUnresolvedDependentMemberType());
8060+
checkSameTypeConstraints(genericParams, &equivClass);
8061+
}
8062+
8063+
for (unsigned i : indices(equivClass.derivedSameTypeComponents)) {
8064+
// Dig out the subject type and its corresponding component.
8065+
auto &component = equivClass.derivedSameTypeComponents[i];
8066+
Type subjectType = component.type;
8067+
8068+
assert(!subjectType->hasError());
8069+
assert(!subjectType->findUnresolvedDependentMemberType());
8070+
8071+
// If this equivalence class is bound to a concrete type, equate the
8072+
// anchor with a concrete type.
8073+
if (Type concreteType = equivClass.concreteType) {
8074+
// If the parent of this anchor is also a concrete type, don't
8075+
// create a requirement.
8076+
if (!subjectType->is<GenericTypeParamType>() &&
8077+
maybeResolveEquivalenceClass(
8078+
subjectType->castTo<DependentMemberType>()->getBase(),
8079+
ArchetypeResolutionKind::WellFormed,
8080+
/*wantExactPotentialArchetype=*/false)
8081+
.getEquivalenceClass(*this)->concreteType)
8082+
continue;
80738083

8074-
// If this equivalence class is bound to a concrete type, equate the
8075-
// anchor with a concrete type.
8076-
if (Type concreteType = equivClass->concreteType) {
8077-
// If the parent of this anchor is also a concrete type, don't
8078-
// create a requirement.
8079-
if (!subjectType->is<GenericTypeParamType>() &&
8080-
maybeResolveEquivalenceClass(
8081-
subjectType->castTo<DependentMemberType>()->getBase(),
8082-
ArchetypeResolutionKind::WellFormed,
8083-
/*wantExactPotentialArchetype=*/false)
8084-
.getEquivalenceClass(*this)->concreteType)
8085-
continue;
8084+
// Drop recursive and invalid concrete-type constraints.
8085+
if (equivClass.recursiveConcreteType ||
8086+
equivClass.invalidConcreteType)
8087+
continue;
80868088

8087-
// Drop recursive and invalid concrete-type constraints.
8088-
if (equivClass->recursiveConcreteType ||
8089-
equivClass->invalidConcreteType)
8089+
// Filter out derived requirements... except for concrete-type
8090+
// requirements on generic parameters. The exception is due to
8091+
// the canonicalization of generic signatures, which never
8092+
// eliminates generic parameters even when they have been
8093+
// mapped to a concrete type.
8094+
if (subjectType->is<GenericTypeParamType>() ||
8095+
component.concreteTypeSource == nullptr ||
8096+
!component.concreteTypeSource->isDerivedRequirement()) {
8097+
recordRequirement(RequirementKind::SameType,
8098+
subjectType, concreteType);
8099+
}
80908100
continue;
8091-
8092-
// Filter out derived requirements... except for concrete-type
8093-
// requirements on generic parameters. The exception is due to
8094-
// the canonicalization of generic signatures, which never
8095-
// eliminates generic parameters even when they have been
8096-
// mapped to a concrete type.
8097-
if (subjectType->is<GenericTypeParamType>() ||
8098-
component.concreteTypeSource == nullptr ||
8099-
!component.concreteTypeSource->isDerivedRequirement()) {
8100-
recordRequirement(RequirementKind::SameType,
8101-
subjectType, concreteType);
81028101
}
8103-
continue;
8104-
}
8105-
8106-
std::function<void()> deferredSameTypeRequirement;
81078102

8108-
// If we're at the last anchor in the component, do nothing;
8109-
if (subject.second + 1 != equivClass->derivedSameTypeComponents.size()) {
8110-
// Form a same-type constraint from this anchor within the component
8111-
// to the next.
8112-
// FIXME: Distinguish between explicit and inferred here?
8113-
auto &nextComponent =
8114-
equivClass->derivedSameTypeComponents[subject.second + 1];
8115-
Type otherSubjectType = nextComponent.type;
8116-
deferredSameTypeRequirement =
8117-
[&recordRequirement, subjectType, otherSubjectType] {
8118-
recordRequirement(RequirementKind::SameType,
8119-
subjectType, otherSubjectType);
8120-
};
8121-
}
8103+
std::function<void()> deferredSameTypeRequirement;
8104+
8105+
// If we're at the last anchor in the component, do nothing;
8106+
if (i + 1 != equivClass.derivedSameTypeComponents.size()) {
8107+
// Form a same-type constraint from this anchor within the component
8108+
// to the next.
8109+
// FIXME: Distinguish between explicit and inferred here?
8110+
auto &nextComponent = equivClass.derivedSameTypeComponents[i + 1];
8111+
Type otherSubjectType = nextComponent.type;
8112+
deferredSameTypeRequirement =
8113+
[&recordRequirement, subjectType, otherSubjectType] {
8114+
recordRequirement(RequirementKind::SameType,
8115+
subjectType, otherSubjectType);
8116+
};
8117+
}
81228118

8123-
SWIFT_DEFER {
8124-
if (deferredSameTypeRequirement) deferredSameTypeRequirement();
8125-
};
8119+
SWIFT_DEFER {
8120+
if (deferredSameTypeRequirement) deferredSameTypeRequirement();
8121+
};
81268122

8127-
// If this is not the first component anchor in its equivalence class,
8128-
// we're done.
8129-
if (subject.second > 0)
8130-
continue;
8123+
// If this is not the first component anchor in its equivalence class,
8124+
// we're done.
8125+
if (i > 0)
8126+
continue;
81318127

8132-
// If we have a superclass, produce a superclass requirement
8133-
if (equivClass->superclass &&
8134-
!equivClass->recursiveSuperclassType &&
8135-
!equivClass->superclass->hasError()) {
8136-
if (hasNonRedundantRequirementSource<Type>(
8137-
equivClass->superclassConstraints,
8138-
RequirementKind::Superclass, *this)) {
8139-
recordRequirement(RequirementKind::Superclass,
8140-
subjectType, equivClass->superclass);
8128+
// If we have a superclass, produce a superclass requirement
8129+
if (equivClass.superclass &&
8130+
!equivClass.recursiveSuperclassType &&
8131+
!equivClass.superclass->hasError()) {
8132+
if (hasNonRedundantRequirementSource<Type>(
8133+
equivClass.superclassConstraints,
8134+
RequirementKind::Superclass, *this)) {
8135+
recordRequirement(RequirementKind::Superclass,
8136+
subjectType, equivClass.superclass);
8137+
}
81418138
}
8142-
}
81438139

8144-
// If we have a layout constraint, produce a layout requirement.
8145-
if (equivClass->layout) {
8146-
if (hasNonRedundantRequirementSource<LayoutConstraint>(
8147-
equivClass->layoutConstraints,
8148-
RequirementKind::Layout, *this)) {
8149-
recordRequirement(RequirementKind::Layout,
8150-
subjectType, equivClass->layout);
8140+
// If we have a layout constraint, produce a layout requirement.
8141+
if (equivClass.layout) {
8142+
if (hasNonRedundantRequirementSource<LayoutConstraint>(
8143+
equivClass.layoutConstraints,
8144+
RequirementKind::Layout, *this)) {
8145+
recordRequirement(RequirementKind::Layout,
8146+
subjectType, equivClass.layout);
8147+
}
81518148
}
8152-
}
81538149

8154-
// Enumerate conformance requirements.
8155-
SmallVector<ProtocolDecl *, 4> protocols;
8150+
// Enumerate conformance requirements.
8151+
SmallVector<ProtocolDecl *, 4> protocols;
81568152

8157-
for (const auto &conforms : equivClass->conformsTo) {
8158-
if (hasNonRedundantRequirementSource<ProtocolDecl *>(
8159-
conforms.second, RequirementKind::Conformance, *this)) {
8160-
protocols.push_back(conforms.first);
8153+
for (const auto &conforms : equivClass.conformsTo) {
8154+
if (hasNonRedundantRequirementSource<ProtocolDecl *>(
8155+
conforms.second, RequirementKind::Conformance, *this)) {
8156+
protocols.push_back(conforms.first);
8157+
}
81618158
}
8162-
}
81638159

8164-
// Sort the protocols in canonical order.
8165-
llvm::array_pod_sort(protocols.begin(), protocols.end(),
8166-
TypeDecl::compare);
8160+
// Sort the protocols in canonical order.
8161+
llvm::array_pod_sort(protocols.begin(), protocols.end(),
8162+
TypeDecl::compare);
81678163

8168-
// Enumerate the conformance requirements.
8169-
for (auto proto : protocols) {
8170-
recordRequirement(RequirementKind::Conformance, subjectType, proto);
8164+
// Enumerate the conformance requirements.
8165+
for (auto proto : protocols) {
8166+
recordRequirement(RequirementKind::Conformance, subjectType, proto);
8167+
}
81718168
}
81728169
}
81738170

0 commit comments

Comments
 (0)