@@ -8013,161 +8013,158 @@ namespace {
8013
8013
8014
8014
return false ;
8015
8015
}
8016
+ } // end anonymous namespace
8017
+
8018
+ static Optional<Requirement> createRequirement (RequirementKind kind,
8019
+ Type depTy,
8020
+ RequirementRHS rhs,
8021
+ TypeArrayView<GenericTypeParamType> genericParams) {
8016
8022
8017
- using SameTypeComponentRef = std::pair<EquivalenceClass *, unsigned > ;
8023
+ depTy = getSugaredDependentType (depTy, genericParams) ;
8018
8024
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
+ }
8020
8046
8021
8047
void GenericSignatureBuilder::enumerateRequirements (
8022
8048
TypeArrayView<GenericTypeParamType> genericParams,
8023
8049
SmallVectorImpl<Requirement> &requirements) {
8024
8050
auto recordRequirement = [&](RequirementKind kind,
8025
8051
Type depTy,
8026
8052
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);
8052
8055
};
8053
8056
8054
8057
// Collect all of the subject types that will be involved in constraints.
8055
- SmallVector<SameTypeComponentRef, 8 > subjects;
8056
8058
for (auto &equivClass : Impl->EquivalenceClasses ) {
8057
8059
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 ;
8073
8083
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 ;
8086
8088
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
+ }
8090
8100
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);
8102
8101
}
8103
- continue ;
8104
- }
8105
-
8106
- std::function<void ()> deferredSameTypeRequirement;
8107
8102
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
+ }
8122
8118
8123
- SWIFT_DEFER {
8124
- if (deferredSameTypeRequirement) deferredSameTypeRequirement ();
8125
- };
8119
+ SWIFT_DEFER {
8120
+ if (deferredSameTypeRequirement) deferredSameTypeRequirement ();
8121
+ };
8126
8122
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 ;
8131
8127
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
+ }
8141
8138
}
8142
- }
8143
8139
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
+ }
8151
8148
}
8152
- }
8153
8149
8154
- // Enumerate conformance requirements.
8155
- SmallVector<ProtocolDecl *, 4 > protocols;
8150
+ // Enumerate conformance requirements.
8151
+ SmallVector<ProtocolDecl *, 4 > protocols;
8156
8152
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
+ }
8161
8158
}
8162
- }
8163
8159
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);
8167
8163
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
+ }
8171
8168
}
8172
8169
}
8173
8170
0 commit comments