Skip to content

Commit a7f2e5c

Browse files
committed
GSB: Use explicit requirement list in enumerateRequirements()
1 parent 74b29ca commit a7f2e5c

File tree

2 files changed

+26
-75
lines changed

2 files changed

+26
-75
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 25 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -7981,26 +7981,6 @@ bool GenericSignatureBuilder::isRedundantExplicitRequirement(
79817981
return (redundantReqs.find(req) != redundantReqs.end());
79827982
}
79837983

7984-
namespace {
7985-
template<typename T>
7986-
bool hasNonRedundantRequirementSource(ArrayRef<Constraint<T>> constraints,
7987-
RequirementKind kind,
7988-
GenericSignatureBuilder &builder) {
7989-
for (auto constraint : constraints) {
7990-
if (constraint.source->isDerivedRequirement())
7991-
continue;
7992-
7993-
auto req = ExplicitRequirement::fromExplicitConstraint(kind, constraint);
7994-
if (builder.isRedundantExplicitRequirement(req))
7995-
continue;
7996-
7997-
return true;
7998-
}
7999-
8000-
return false;
8001-
}
8002-
} // end anonymous namespace
8003-
80047984
static Optional<Requirement> createRequirement(RequirementKind kind,
80057985
Type depTy,
80067986
RequirementRHS rhs,
@@ -8079,7 +8059,29 @@ void GenericSignatureBuilder::enumerateRequirements(
80798059
requirements.push_back(*req);
80808060
};
80818061

8082-
// Collect all of the subject types that will be involved in constraints.
8062+
// Collect all non-same type requirements.
8063+
for (auto &req : Impl->ExplicitRequirements) {
8064+
if (isRedundantExplicitRequirement(req))
8065+
continue;
8066+
8067+
auto depTy = getCanonicalTypeInContext(
8068+
req.getSource()->getStoredType(), { });
8069+
8070+
// FIXME: This should be an assert once we ensure that concrete
8071+
// same-type requirements always mark other requirements on the
8072+
// same subject type as redundant or conflicting.
8073+
if (!depTy->isTypeParameter())
8074+
continue;
8075+
8076+
auto rhs = req.getRHS();
8077+
if (auto constraintType = rhs.dyn_cast<Type>()) {
8078+
rhs = getCanonicalTypeInContext(constraintType, genericParams);
8079+
}
8080+
8081+
recordRequirement(req.getKind(), depTy, rhs);
8082+
}
8083+
8084+
// Collect all same type requirements.
80838085
for (auto &equivClass : Impl->EquivalenceClasses) {
80848086
if (equivClass.derivedSameTypeComponents.empty()) {
80858087
checkSameTypeConstraints(genericParams, &equivClass);
@@ -8127,67 +8129,16 @@ void GenericSignatureBuilder::enumerateRequirements(
81278129
continue;
81288130
}
81298131

8130-
std::function<void()> deferredSameTypeRequirement;
8131-
81328132
// If we're at the last anchor in the component, do nothing;
81338133
if (i + 1 != equivClass.derivedSameTypeComponents.size()) {
81348134
// Form a same-type constraint from this anchor within the component
81358135
// to the next.
81368136
// FIXME: Distinguish between explicit and inferred here?
81378137
auto &nextComponent = equivClass.derivedSameTypeComponents[i + 1];
81388138
Type otherSubjectType = nextComponent.type;
8139-
deferredSameTypeRequirement =
8140-
[&recordRequirement, subjectType, otherSubjectType] {
8141-
recordRequirement(RequirementKind::SameType,
8142-
subjectType, otherSubjectType);
8143-
};
8144-
}
8145-
8146-
SWIFT_DEFER {
8147-
if (deferredSameTypeRequirement) deferredSameTypeRequirement();
8148-
};
8149-
8150-
// If this is not the first component anchor in its equivalence class,
8151-
// we're done.
8152-
if (i > 0)
8153-
continue;
8154-
8155-
// If we have a superclass, produce a superclass requirement
8156-
if (auto superclass = equivClass.superclass) {
8157-
superclass = getCanonicalTypeInContext(superclass, genericParams);
8158-
8159-
if (!equivClass.recursiveSuperclassType &&
8160-
hasNonRedundantRequirementSource<Type>(
8161-
equivClass.superclassConstraints,
8162-
RequirementKind::Superclass, *this)) {
8163-
recordRequirement(RequirementKind::Superclass,
8164-
subjectType, superclass);
8165-
}
8166-
}
8167-
8168-
// If we have a layout constraint, produce a layout requirement.
8169-
if (equivClass.layout) {
8170-
if (hasNonRedundantRequirementSource<LayoutConstraint>(
8171-
equivClass.layoutConstraints,
8172-
RequirementKind::Layout, *this)) {
8173-
recordRequirement(RequirementKind::Layout,
8174-
subjectType, equivClass.layout);
8175-
}
8176-
}
8177-
8178-
// Enumerate conformance requirements.
8179-
SmallVector<ProtocolDecl *, 4> protocols;
8180-
8181-
for (const auto &conforms : equivClass.conformsTo) {
8182-
if (hasNonRedundantRequirementSource<ProtocolDecl *>(
8183-
conforms.second, RequirementKind::Conformance, *this)) {
8184-
protocols.push_back(conforms.first);
8185-
}
8186-
}
81878139

8188-
// Enumerate the conformance requirements.
8189-
for (auto proto : protocols) {
8190-
recordRequirement(RequirementKind::Conformance, subjectType, proto);
8140+
recordRequirement(RequirementKind::SameType,
8141+
subjectType, otherSubjectType);
81918142
}
81928143
}
81938144
}

test/IDE/print_ast_tc_decls.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -619,7 +619,7 @@ struct d0200_EscapedIdentifiers {
619619

620620
func `func`<`let`: `protocol`, `where`>(
621621
class: Int, struct: `protocol`, foo: `let`, bar: `where`) where `where` : `protocol` {}
622-
// PASS_COMMON-NEXT: {{^}} func `func`<`let`, `where`>(class: Int, struct: {{(d0200_EscapedIdentifiers.)?}}`protocol`, foo: `let`, bar: `where`) where `let` : {{(d0200_EscapedIdentifiers.)?}}`protocol`, `where` : {{(d0200_EscapedIdentifiers.)?}}`protocol`{{$}}
622+
// PASS_COMMON-NEXT: {{^}} func `func`<`let`, `where`>(class: Int, struct: {{(d0200_EscapedIdentifiers.)?}}`protocol`, foo: `let`, bar: `where`) where `let` : {{(d0200_EscapedIdentifiers.)?}}`class`, `where` : {{(d0200_EscapedIdentifiers.)?}}`class`{{$}}
623623

624624
var `var`: `struct` = `struct`()
625625
// PASS_COMMON-NEXT: {{^}} @_hasInitialValue var `var`: {{(d0200_EscapedIdentifiers.)?}}`struct`{{$}}

0 commit comments

Comments
 (0)