Skip to content

Commit 3cf613a

Browse files
committed
AST: Teach GenericSignatureBuilder about layout constraints that come from inheritance clauses
For now, NFC, but soon this will be <T : AnyObject>.
1 parent 256f349 commit 3cf613a

File tree

1 file changed

+46
-38
lines changed

1 file changed

+46
-38
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 46 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -2195,31 +2195,35 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
21952195
/// types.
21962196
static ConstraintResult visitInherited(
21972197
ArrayRef<TypeLoc> inheritedTypes,
2198-
llvm::function_ref<ConstraintResult(Type, const TypeRepr *)> visitor) {
2198+
llvm::function_ref<ConstraintResult(Type, const TypeRepr *)> visitType,
2199+
llvm::function_ref<ConstraintResult(LayoutConstraint, const TypeRepr *)> visitLayout) {
21992200
// Local function that (recursively) adds inherited types.
22002201
ConstraintResult result = ConstraintResult::Resolved;
22012202
std::function<void(Type, const TypeRepr *)> visitInherited;
22022203

22032204
// FIXME: Should this whole thing use getExistentialLayout() instead?
22042205

22052206
visitInherited = [&](Type inheritedType, const TypeRepr *typeRepr) {
2206-
// Decompose protocol compositions.
2207-
auto composition = dyn_cast_or_null<CompositionTypeRepr>(typeRepr);
2208-
if (auto compositionType
2209-
= inheritedType->getAs<ProtocolCompositionType>()) {
2210-
unsigned index = 0;
2211-
for (auto protoType : compositionType->getMembers()) {
2212-
if (composition && index < composition->getTypes().size())
2213-
visitInherited(protoType, composition->getTypes()[index]);
2214-
else
2215-
visitInherited(protoType, typeRepr);
2216-
2217-
++index;
2207+
// Decompose explicitly-written protocol compositions.
2208+
if (auto composition = dyn_cast_or_null<CompositionTypeRepr>(typeRepr)) {
2209+
if (auto compositionType
2210+
= inheritedType->getAs<ProtocolCompositionType>()) {
2211+
unsigned index = 0;
2212+
for (auto memberType : compositionType->getMembers()) {
2213+
visitInherited(memberType, composition->getTypes()[index]);
2214+
index++;
2215+
}
2216+
2217+
auto layout = compositionType->getExistentialLayout()
2218+
.getLayoutConstraint();
2219+
if (layout)
2220+
visitLayout(layout, composition);
2221+
2222+
return;
22182223
}
2219-
return;
22202224
}
22212225

2222-
auto recursiveResult = visitor(inheritedType, typeRepr);
2226+
auto recursiveResult = visitType(inheritedType, typeRepr);
22232227
if (isErrorResult(recursiveResult) && !isErrorResult(result))
22242228
result = recursiveResult;
22252229
};
@@ -2935,36 +2939,40 @@ ConstraintResult GenericSignatureBuilder::addInheritedRequirements(
29352939
if (auto resolver = getLazyResolver())
29362940
resolver->resolveInheritanceClause(decl);
29372941

2938-
return visitInherited(
2939-
decl->getInherited(),
2940-
[&](Type inheritedType, const TypeRepr *typeRepr) {
2941-
// Local function to get the source.
2942-
auto getFloatingSource = [&] {
2943-
if (parentSource) {
2944-
if (auto assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
2945-
auto proto = assocType->getProtocol();
2946-
return FloatingRequirementSource::viaProtocolRequirement(
2947-
parentSource, proto, typeRepr);
2948-
}
2949-
2950-
auto proto = cast<ProtocolDecl>(decl);
2942+
// Local function to get the source.
2943+
auto getFloatingSource = [&](const TypeRepr *typeRepr) {
2944+
if (parentSource) {
2945+
if (auto assocType = dyn_cast<AssociatedTypeDecl>(decl)) {
2946+
auto proto = assocType->getProtocol();
29512947
return FloatingRequirementSource::viaProtocolRequirement(
2952-
parentSource, proto, typeRepr);
2948+
parentSource, proto, typeRepr);
29532949
}
29542950

2955-
// Explicit requirement.
2956-
if (typeRepr)
2957-
return FloatingRequirementSource::forExplicit(typeRepr);
2951+
auto proto = cast<ProtocolDecl>(decl);
2952+
return FloatingRequirementSource::viaProtocolRequirement(
2953+
parentSource, proto, typeRepr);
2954+
}
29582955

2959-
// An abstract explicit requirement.
2960-
return FloatingRequirementSource::forAbstract();
2961-
};
2956+
// Explicit requirement.
2957+
if (typeRepr)
2958+
return FloatingRequirementSource::forExplicit(typeRepr);
29622959

2963-
// Protocol requirement.
2964-
return addTypeRequirement(pa, inheritedType, getFloatingSource(),
2960+
// An abstract explicit requirement.
2961+
return FloatingRequirementSource::forAbstract();
2962+
};
2963+
2964+
auto visitType = [&](Type inheritedType, const TypeRepr *typeRepr) {
2965+
return addTypeRequirement(pa, inheritedType, getFloatingSource(typeRepr),
29652966
UnresolvedHandlingKind::GenerateConstraints,
29662967
&visited);
2967-
});
2968+
};
2969+
2970+
auto visitLayout = [&](LayoutConstraint layout, const TypeRepr *typeRepr) {
2971+
return addLayoutRequirement(pa, layout, getFloatingSource(typeRepr),
2972+
UnresolvedHandlingKind::GenerateConstraints);
2973+
};
2974+
2975+
return visitInherited(decl->getInherited(), visitType, visitLayout);
29682976
}
29692977

29702978
ConstraintResult GenericSignatureBuilder::addRequirement(const RequirementRepr *req) {

0 commit comments

Comments
 (0)