Skip to content

Commit 24de191

Browse files
committed
GSB: Merge collectRequirements() with enumerateRequirements()
1 parent e0c7627 commit 24de191

File tree

2 files changed

+74
-105
lines changed

2 files changed

+74
-105
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 1 addition & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -533,16 +533,9 @@ class GenericSignatureBuilder {
533533

534534
/// Enumerate the requirements that describe the signature of this
535535
/// generic signature builder.
536-
///
537-
/// \param f A function object that will be passed each requirement
538-
/// and requirement source.
539536
void enumerateRequirements(
540537
TypeArrayView<GenericTypeParamType> genericParams,
541-
llvm::function_ref<
542-
void (RequirementKind kind,
543-
Type type,
544-
RequirementRHS constraint,
545-
const RequirementSource *source)> f);
538+
SmallVectorImpl<Requirement> &requirements);
546539

547540
/// Retrieve the generic parameters used to describe the generic
548541
/// signature being built.

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 73 additions & 97 deletions
Original file line numberDiff line numberDiff line change
@@ -6923,11 +6923,34 @@ namespace {
69236923

69246924
void GenericSignatureBuilder::enumerateRequirements(
69256925
TypeArrayView<GenericTypeParamType> genericParams,
6926-
llvm::function_ref<
6927-
void (RequirementKind kind,
6928-
Type type,
6929-
RequirementRHS constraint,
6930-
const RequirementSource *source)> f) {
6926+
SmallVectorImpl<Requirement> &requirements) {
6927+
auto recordRequirement = [&](RequirementKind kind,
6928+
Type depTy,
6929+
RequirementRHS type) {
6930+
depTy = getSugaredDependentType(depTy, genericParams);
6931+
6932+
if (auto concreteTy = type.dyn_cast<Type>()) {
6933+
if (concreteTy->hasError())
6934+
return;
6935+
6936+
// Drop requirements involving concrete types containing
6937+
// unresolved associated types.
6938+
if (concreteTy->findUnresolvedDependentMemberType()) {
6939+
assert(Impl->HadAnyError);
6940+
return;
6941+
}
6942+
6943+
if (concreteTy->isTypeParameter())
6944+
concreteTy = getSugaredDependentType(concreteTy, genericParams);
6945+
6946+
requirements.push_back(Requirement(kind, depTy, concreteTy));
6947+
} else {
6948+
auto layoutConstraint = type.get<LayoutConstraint>();
6949+
requirements.push_back(Requirement(kind, depTy, layoutConstraint));
6950+
return;
6951+
}
6952+
};
6953+
69316954
// Collect all of the subject types that will be involved in constraints.
69326955
SmallVector<SameTypeComponentRef, 8> subjects;
69336956
for (auto &equivClass : Impl->EquivalenceClasses) {
@@ -6945,6 +6968,9 @@ void GenericSignatureBuilder::enumerateRequirements(
69456968
auto &component = equivClass->derivedSameTypeComponents[subject.second];
69466969
Type subjectType = component.type;
69476970

6971+
assert(!subjectType->hasError());
6972+
assert(!subjectType->findUnresolvedDependentMemberType());
6973+
69486974
// If this equivalence class is bound to a concrete type, equate the
69496975
// anchor with a concrete type.
69506976
if (Type concreteType = equivClass->concreteType) {
@@ -6958,17 +6984,22 @@ void GenericSignatureBuilder::enumerateRequirements(
69586984
.getEquivalenceClass(*this)->concreteType)
69596985
continue;
69606986

6961-
auto source =
6962-
component.concreteTypeSource
6963-
? component.concreteTypeSource
6964-
: RequirementSource::forAbstract(*this, subjectType);
6965-
69666987
// Drop recursive and invalid concrete-type constraints.
69676988
if (equivClass->recursiveConcreteType ||
69686989
equivClass->invalidConcreteType)
69696990
continue;
69706991

6971-
f(RequirementKind::SameType, subjectType, concreteType, source);
6992+
// Filter out derived requirements... except for concrete-type
6993+
// requirements on generic parameters. The exception is due to
6994+
// the canonicalization of generic signatures, which never
6995+
// eliminates generic parameters even when they have been
6996+
// mapped to a concrete type.
6997+
if (subjectType->is<GenericTypeParamType>() ||
6998+
component.concreteTypeSource == nullptr ||
6999+
!component.concreteTypeSource->isDerivedRequirement()) {
7000+
recordRequirement(RequirementKind::SameType,
7001+
subjectType, concreteType);
7002+
}
69727003
continue;
69737004
}
69747005

@@ -6983,9 +7014,9 @@ void GenericSignatureBuilder::enumerateRequirements(
69837014
equivClass->derivedSameTypeComponents[subject.second + 1];
69847015
Type otherSubjectType = nextComponent.type;
69857016
deferredSameTypeRequirement =
6986-
[&f, subjectType, otherSubjectType, this] {
6987-
f(RequirementKind::SameType, subjectType, otherSubjectType,
6988-
RequirementSource::forAbstract(*this, otherSubjectType));
7017+
[&recordRequirement, subjectType, otherSubjectType] {
7018+
recordRequirement(RequirementKind::SameType,
7019+
subjectType, otherSubjectType);
69897020
};
69907021
}
69917022

@@ -7008,8 +7039,10 @@ void GenericSignatureBuilder::enumerateRequirements(
70087039
return type->isEqual(equivClass->superclass);
70097040
});
70107041

7011-
f(RequirementKind::Superclass, subjectType, equivClass->superclass,
7012-
bestSource);
7042+
if (!bestSource->isDerivedRequirement()) {
7043+
recordRequirement(RequirementKind::Superclass,
7044+
subjectType, equivClass->superclass);
7045+
}
70137046
}
70147047

70157048
// If we have a layout constraint, produce a layout requirement.
@@ -7020,25 +7053,24 @@ void GenericSignatureBuilder::enumerateRequirements(
70207053
return layout == equivClass->layout;
70217054
});
70227055

7023-
f(RequirementKind::Layout, subjectType, equivClass->layout,
7024-
bestSource);
7056+
if (!bestSource->isDerivedRequirement()) {
7057+
recordRequirement(RequirementKind::Layout,
7058+
subjectType, equivClass->layout);
7059+
}
70257060
}
70267061

70277062
// Enumerate conformance requirements.
70287063
SmallVector<ProtocolDecl *, 4> protocols;
7029-
DenseMap<ProtocolDecl *, const RequirementSource *> protocolSources;
70307064

70317065
for (const auto &conforms : equivClass->conformsTo) {
7032-
protocols.push_back(conforms.first);
7033-
assert(protocolSources.count(conforms.first) == 0 &&
7034-
"redundant protocol requirement?");
7066+
auto *bestSource = getBestConstraintSource<ProtocolDecl *>(
7067+
conforms.second,
7068+
[&](ProtocolDecl *proto) {
7069+
return proto == conforms.first;
7070+
});
70357071

7036-
protocolSources.insert(
7037-
{conforms.first,
7038-
getBestConstraintSource<ProtocolDecl *>(conforms.second,
7039-
[&](ProtocolDecl *proto) {
7040-
return proto == conforms.first;
7041-
})});
7072+
if (!bestSource->isDerivedRequirement())
7073+
protocols.push_back(conforms.first);
70427074
}
70437075

70447076
// Sort the protocols in canonical order.
@@ -7047,12 +7079,19 @@ void GenericSignatureBuilder::enumerateRequirements(
70477079

70487080
// Enumerate the conformance requirements.
70497081
for (auto proto : protocols) {
7050-
assert(protocolSources.count(proto) == 1 && "Missing conformance?");
7051-
f(RequirementKind::Conformance, subjectType,
7052-
proto->getDeclaredInterfaceType(),
7053-
protocolSources.find(proto)->second);
7082+
recordRequirement(RequirementKind::Conformance, subjectType,
7083+
proto->getDeclaredInterfaceType());
70547084
}
7055-
};
7085+
}
7086+
7087+
// Sort the subject types in canonical order. This needs to be a stable sort
7088+
// so that the relative order of requirements that have the same subject type
7089+
// is preserved.
7090+
std::stable_sort(requirements.begin(), requirements.end(),
7091+
[](const Requirement &lhs, const Requirement &rhs) {
7092+
return compareDependentTypes(lhs.getFirstType(),
7093+
rhs.getFirstType()) < 0;
7094+
});
70567095
}
70577096

70587097
void GenericSignatureBuilder::dump() {
@@ -7083,69 +7122,6 @@ void GenericSignatureBuilder::addGenericSignature(GenericSignature sig) {
70837122
addRequirement(reqt, FloatingRequirementSource::forAbstract(), nullptr);
70847123
}
70857124

7086-
/// Collect the set of requirements placed on the given generic parameters and
7087-
/// their associated types.
7088-
static void collectRequirements(GenericSignatureBuilder &builder,
7089-
TypeArrayView<GenericTypeParamType> params,
7090-
SmallVectorImpl<Requirement> &requirements) {
7091-
builder.enumerateRequirements(
7092-
params,
7093-
[&](RequirementKind kind,
7094-
Type depTy,
7095-
RequirementRHS type,
7096-
const RequirementSource *source) {
7097-
// Filter out derived requirements... except for concrete-type requirements
7098-
// on generic parameters. The exception is due to the canonicalization of
7099-
// generic signatures, which never eliminates generic parameters even when
7100-
// they have been mapped to a concrete type.
7101-
if (source->isDerivedRequirement() &&
7102-
!(kind == RequirementKind::SameType &&
7103-
depTy->is<GenericTypeParamType>() &&
7104-
type.is<Type>()))
7105-
return;
7106-
7107-
if (depTy->hasError())
7108-
return;
7109-
7110-
assert(!depTy->findUnresolvedDependentMemberType() &&
7111-
"Unresolved dependent member type in requirements");
7112-
7113-
depTy = getSugaredDependentType(depTy, params);
7114-
7115-
Type repTy;
7116-
if (auto concreteTy = type.dyn_cast<Type>()) {
7117-
// Maybe we were equated to a concrete or dependent type...
7118-
repTy = concreteTy;
7119-
7120-
// Drop requirements involving concrete types containing
7121-
// unresolved associated types.
7122-
if (repTy->findUnresolvedDependentMemberType())
7123-
return;
7124-
7125-
if (repTy->isTypeParameter())
7126-
repTy = getSugaredDependentType(repTy, params);
7127-
} else {
7128-
auto layoutConstraint = type.get<LayoutConstraint>();
7129-
requirements.push_back(Requirement(kind, depTy, layoutConstraint));
7130-
return;
7131-
}
7132-
7133-
if (repTy->hasError())
7134-
return;
7135-
7136-
requirements.push_back(Requirement(kind, depTy, repTy));
7137-
});
7138-
7139-
// Sort the subject types in canonical order. This needs to be a stable sort
7140-
// so that the relative order of requirements that have the same subject type
7141-
// is preserved.
7142-
std::stable_sort(requirements.begin(), requirements.end(),
7143-
[](const Requirement &lhs, const Requirement &rhs) {
7144-
return compareDependentTypes(lhs.getFirstType(),
7145-
rhs.getFirstType()) < 0;
7146-
});
7147-
}
7148-
71497125
GenericSignature GenericSignatureBuilder::computeGenericSignature(
71507126
bool allowConcreteGenericParams,
71517127
bool allowBuilderToMove) && {
@@ -7154,7 +7130,7 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
71547130

71557131
// Collect the requirements placed on the generic parameter types.
71567132
SmallVector<Requirement, 4> requirements;
7157-
collectRequirements(*this, getGenericParams(), requirements);
7133+
enumerateRequirements(getGenericParams(), requirements);
71587134

71597135
// Form the generic signature.
71607136
auto sig = GenericSignature::get(getGenericParams(), requirements);

0 commit comments

Comments
 (0)