@@ -6923,11 +6923,34 @@ namespace {
6923
6923
6924
6924
void GenericSignatureBuilder::enumerateRequirements (
6925
6925
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
+
6931
6954
// Collect all of the subject types that will be involved in constraints.
6932
6955
SmallVector<SameTypeComponentRef, 8 > subjects;
6933
6956
for (auto &equivClass : Impl->EquivalenceClasses ) {
@@ -6945,6 +6968,9 @@ void GenericSignatureBuilder::enumerateRequirements(
6945
6968
auto &component = equivClass->derivedSameTypeComponents [subject.second ];
6946
6969
Type subjectType = component.type ;
6947
6970
6971
+ assert (!subjectType->hasError ());
6972
+ assert (!subjectType->findUnresolvedDependentMemberType ());
6973
+
6948
6974
// If this equivalence class is bound to a concrete type, equate the
6949
6975
// anchor with a concrete type.
6950
6976
if (Type concreteType = equivClass->concreteType ) {
@@ -6958,17 +6984,22 @@ void GenericSignatureBuilder::enumerateRequirements(
6958
6984
.getEquivalenceClass (*this )->concreteType )
6959
6985
continue ;
6960
6986
6961
- auto source =
6962
- component.concreteTypeSource
6963
- ? component.concreteTypeSource
6964
- : RequirementSource::forAbstract (*this , subjectType);
6965
-
6966
6987
// Drop recursive and invalid concrete-type constraints.
6967
6988
if (equivClass->recursiveConcreteType ||
6968
6989
equivClass->invalidConcreteType )
6969
6990
continue ;
6970
6991
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
+ }
6972
7003
continue ;
6973
7004
}
6974
7005
@@ -6983,9 +7014,9 @@ void GenericSignatureBuilder::enumerateRequirements(
6983
7014
equivClass->derivedSameTypeComponents [subject.second + 1 ];
6984
7015
Type otherSubjectType = nextComponent.type ;
6985
7016
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);
6989
7020
};
6990
7021
}
6991
7022
@@ -7008,8 +7039,10 @@ void GenericSignatureBuilder::enumerateRequirements(
7008
7039
return type->isEqual (equivClass->superclass );
7009
7040
});
7010
7041
7011
- f (RequirementKind::Superclass, subjectType, equivClass->superclass ,
7012
- bestSource);
7042
+ if (!bestSource->isDerivedRequirement ()) {
7043
+ recordRequirement (RequirementKind::Superclass,
7044
+ subjectType, equivClass->superclass );
7045
+ }
7013
7046
}
7014
7047
7015
7048
// If we have a layout constraint, produce a layout requirement.
@@ -7020,25 +7053,24 @@ void GenericSignatureBuilder::enumerateRequirements(
7020
7053
return layout == equivClass->layout ;
7021
7054
});
7022
7055
7023
- f (RequirementKind::Layout, subjectType, equivClass->layout ,
7024
- bestSource);
7056
+ if (!bestSource->isDerivedRequirement ()) {
7057
+ recordRequirement (RequirementKind::Layout,
7058
+ subjectType, equivClass->layout );
7059
+ }
7025
7060
}
7026
7061
7027
7062
// Enumerate conformance requirements.
7028
7063
SmallVector<ProtocolDecl *, 4 > protocols;
7029
- DenseMap<ProtocolDecl *, const RequirementSource *> protocolSources;
7030
7064
7031
7065
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
+ });
7035
7071
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 );
7042
7074
}
7043
7075
7044
7076
// Sort the protocols in canonical order.
@@ -7047,12 +7079,19 @@ void GenericSignatureBuilder::enumerateRequirements(
7047
7079
7048
7080
// Enumerate the conformance requirements.
7049
7081
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 ());
7054
7084
}
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
+ });
7056
7095
}
7057
7096
7058
7097
void GenericSignatureBuilder::dump () {
@@ -7083,69 +7122,6 @@ void GenericSignatureBuilder::addGenericSignature(GenericSignature sig) {
7083
7122
addRequirement (reqt, FloatingRequirementSource::forAbstract (), nullptr );
7084
7123
}
7085
7124
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
-
7149
7125
GenericSignature GenericSignatureBuilder::computeGenericSignature (
7150
7126
bool allowConcreteGenericParams,
7151
7127
bool allowBuilderToMove) && {
@@ -7154,7 +7130,7 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
7154
7130
7155
7131
// Collect the requirements placed on the generic parameter types.
7156
7132
SmallVector<Requirement, 4 > requirements;
7157
- collectRequirements (* this , getGenericParams (), requirements);
7133
+ enumerateRequirements ( getGenericParams (), requirements);
7158
7134
7159
7135
// Form the generic signature.
7160
7136
auto sig = GenericSignature::get (getGenericParams (), requirements);
0 commit comments