@@ -1710,7 +1710,7 @@ bool EquivalenceClass::recordConformanceConstraint(
1710
1710
GenericSignatureBuilder &builder,
1711
1711
ResolvedType type,
1712
1712
ProtocolDecl *proto,
1713
- FloatingRequirementSource source) {
1713
+ const RequirementSource * source) {
1714
1714
// If we haven't seen a conformance to this protocol yet, add it.
1715
1715
bool inserted = false ;
1716
1716
auto known = conformsTo.find (proto);
@@ -1730,8 +1730,7 @@ bool EquivalenceClass::recordConformanceConstraint(
1730
1730
}
1731
1731
1732
1732
// Record this conformance source.
1733
- known->second .push_back ({type.getUnresolvedType (), proto,
1734
- source.getSource (builder, type)});
1733
+ known->second .push_back ({type.getUnresolvedType (), proto, source});
1735
1734
++NumConformanceConstraints;
1736
1735
1737
1736
return inserted;
@@ -4167,13 +4166,15 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
4167
4166
ResolvedType type,
4168
4167
ProtocolDecl *proto,
4169
4168
FloatingRequirementSource source) {
4169
+ auto resolvedSource = source.getSource (*this , type);
4170
+
4170
4171
// Add the conformance requirement, bailing out earlier if we've already
4171
4172
// seen it.
4172
4173
auto equivClass = type.getEquivalenceClass (*this );
4173
- if (!equivClass->recordConformanceConstraint (*this , type, proto, source))
4174
+ if (!equivClass->recordConformanceConstraint (*this , type, proto,
4175
+ resolvedSource))
4174
4176
return ConstraintResult::Resolved;
4175
4177
4176
- auto resolvedSource = source.getSource (*this , type);
4177
4178
return expandConformanceRequirement (type, proto, resolvedSource,
4178
4179
/* onlySameTypeRequirements=*/ false );
4179
4180
}
@@ -4325,7 +4326,7 @@ ConstraintResult GenericSignatureBuilder::addSuperclassRequirementDirect(
4325
4326
++NumSuperclassConstraints;
4326
4327
4327
4328
// Update the equivalence class with the constraint.
4328
- if (!updateSuperclass (type, superclass, source ))
4329
+ if (!updateSuperclass (type, superclass, resolvedSource ))
4329
4330
++NumSuperclassConstraintsExtra;
4330
4331
4331
4332
return ConstraintResult::Resolved;
@@ -6902,14 +6903,14 @@ void GenericSignatureBuilder::checkLayoutConstraints(
6902
6903
namespace {
6903
6904
// / Retrieve the best requirement source from a set of constraints.
6904
6905
template <typename T>
6905
- Optional< const RequirementSource *>
6906
+ const RequirementSource *
6906
6907
getBestConstraintSource (ArrayRef<Constraint<T>> constraints,
6907
6908
llvm::function_ref<bool (const T&)> matches) {
6908
- Optional< const RequirementSource *> bestSource;
6909
+ const RequirementSource *bestSource = nullptr ;
6909
6910
for (const auto &constraint : constraints) {
6910
6911
if (!matches (constraint.value )) continue ;
6911
6912
6912
- if (!bestSource || constraint.source ->compare (* bestSource) < 0 )
6913
+ if (!bestSource || constraint.source ->compare (bestSource) < 0 )
6913
6914
bestSource = constraint.source ;
6914
6915
}
6915
6916
@@ -6922,11 +6923,34 @@ namespace {
6922
6923
6923
6924
void GenericSignatureBuilder::enumerateRequirements (
6924
6925
TypeArrayView<GenericTypeParamType> genericParams,
6925
- llvm::function_ref<
6926
- void (RequirementKind kind,
6927
- Type type,
6928
- RequirementRHS constraint,
6929
- 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
+
6930
6954
// Collect all of the subject types that will be involved in constraints.
6931
6955
SmallVector<SameTypeComponentRef, 8 > subjects;
6932
6956
for (auto &equivClass : Impl->EquivalenceClasses ) {
@@ -6944,6 +6968,9 @@ void GenericSignatureBuilder::enumerateRequirements(
6944
6968
auto &component = equivClass->derivedSameTypeComponents [subject.second ];
6945
6969
Type subjectType = component.type ;
6946
6970
6971
+ assert (!subjectType->hasError ());
6972
+ assert (!subjectType->findUnresolvedDependentMemberType ());
6973
+
6947
6974
// If this equivalence class is bound to a concrete type, equate the
6948
6975
// anchor with a concrete type.
6949
6976
if (Type concreteType = equivClass->concreteType ) {
@@ -6957,17 +6984,22 @@ void GenericSignatureBuilder::enumerateRequirements(
6957
6984
.getEquivalenceClass (*this )->concreteType )
6958
6985
continue ;
6959
6986
6960
- auto source =
6961
- component.concreteTypeSource
6962
- ? component.concreteTypeSource
6963
- : RequirementSource::forAbstract (*this , subjectType);
6964
-
6965
6987
// Drop recursive and invalid concrete-type constraints.
6966
6988
if (equivClass->recursiveConcreteType ||
6967
6989
equivClass->invalidConcreteType )
6968
6990
continue ;
6969
6991
6970
- 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
+ }
6971
7003
continue ;
6972
7004
}
6973
7005
@@ -6982,9 +7014,9 @@ void GenericSignatureBuilder::enumerateRequirements(
6982
7014
equivClass->derivedSameTypeComponents [subject.second + 1 ];
6983
7015
Type otherSubjectType = nextComponent.type ;
6984
7016
deferredSameTypeRequirement =
6985
- [&f , subjectType, otherSubjectType, this ] {
6986
- f (RequirementKind::SameType, subjectType, otherSubjectType ,
6987
- RequirementSource::forAbstract (* this , otherSubjectType) );
7017
+ [&recordRequirement , subjectType, otherSubjectType] {
7018
+ recordRequirement (RequirementKind::SameType,
7019
+ subjectType , otherSubjectType);
6988
7020
};
6989
7021
}
6990
7022
@@ -6998,18 +7030,19 @@ void GenericSignatureBuilder::enumerateRequirements(
6998
7030
continue ;
6999
7031
7000
7032
// If we have a superclass, produce a superclass requirement
7001
- if (equivClass->superclass && !equivClass->recursiveSuperclassType ) {
7033
+ if (equivClass->superclass &&
7034
+ !equivClass->recursiveSuperclassType &&
7035
+ !equivClass->superclass ->hasError ()) {
7002
7036
auto bestSource =
7003
7037
getBestConstraintSource<Type>(equivClass->superclassConstraints ,
7004
7038
[&](const Type &type) {
7005
7039
return type->isEqual (equivClass->superclass );
7006
7040
});
7007
7041
7008
- if (!bestSource)
7009
- bestSource = RequirementSource::forAbstract (*this , subjectType);
7010
-
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.
@@ -7019,27 +7052,25 @@ void GenericSignatureBuilder::enumerateRequirements(
7019
7052
[&](const LayoutConstraint &layout) {
7020
7053
return layout == equivClass->layout ;
7021
7054
});
7022
- if (!bestSource)
7023
- bestSource = RequirementSource::forAbstract (*this , subjectType);
7024
7055
7025
- f (RequirementKind::Layout, subjectType, equivClass->layout , *bestSource);
7056
+ if (!bestSource->isDerivedRequirement ()) {
7057
+ recordRequirement (RequirementKind::Layout,
7058
+ subjectType, equivClass->layout );
7059
+ }
7026
7060
}
7027
7061
7028
7062
// Enumerate conformance requirements.
7029
7063
SmallVector<ProtocolDecl *, 4 > protocols;
7030
- DenseMap<ProtocolDecl *, const RequirementSource *> protocolSources;
7031
7064
7032
7065
for (const auto &conforms : equivClass->conformsTo ) {
7033
- protocols.push_back (conforms.first );
7034
- assert (protocolSources.count (conforms.first ) == 0 &&
7035
- " redundant protocol requirement?" );
7066
+ auto *bestSource = getBestConstraintSource<ProtocolDecl *>(
7067
+ conforms.second ,
7068
+ [&](ProtocolDecl *proto) {
7069
+ return proto == conforms.first ;
7070
+ });
7036
7071
7037
- protocolSources.insert (
7038
- {conforms.first ,
7039
- *getBestConstraintSource<ProtocolDecl *>(conforms.second ,
7040
- [&](ProtocolDecl *proto) {
7041
- return proto == conforms.first ;
7042
- })});
7072
+ if (!bestSource->isDerivedRequirement ())
7073
+ protocols.push_back (conforms.first );
7043
7074
}
7044
7075
7045
7076
// Sort the protocols in canonical order.
@@ -7048,54 +7079,26 @@ void GenericSignatureBuilder::enumerateRequirements(
7048
7079
7049
7080
// Enumerate the conformance requirements.
7050
7081
for (auto proto : protocols) {
7051
- assert (protocolSources.count (proto) == 1 && " Missing conformance?" );
7052
- f (RequirementKind::Conformance, subjectType,
7053
- proto->getDeclaredInterfaceType (),
7054
- protocolSources.find (proto)->second );
7082
+ recordRequirement (RequirementKind::Conformance, subjectType,
7083
+ proto->getDeclaredInterfaceType ());
7055
7084
}
7056
- };
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
+ });
7057
7095
}
7058
7096
7059
7097
void GenericSignatureBuilder::dump () {
7060
7098
dump (llvm::errs ());
7061
7099
}
7062
7100
7063
7101
void GenericSignatureBuilder::dump (llvm::raw_ostream &out) {
7064
- out << " Requirements:" ;
7065
- enumerateRequirements (getGenericParams (),
7066
- [&](RequirementKind kind,
7067
- Type type,
7068
- RequirementRHS constraint,
7069
- const RequirementSource *source) {
7070
- switch (kind) {
7071
- case RequirementKind::Conformance:
7072
- case RequirementKind::Superclass:
7073
- out << " \n " ;
7074
- out << type.getString () << " : "
7075
- << constraint.get <Type>().getString () << " [" ;
7076
- source->print (out, &Context.SourceMgr );
7077
- out << " ]" ;
7078
- break ;
7079
- case RequirementKind::Layout:
7080
- out << " \n " ;
7081
- out << type.getString () << " : "
7082
- << constraint.get <LayoutConstraint>().getString () << " [" ;
7083
- source->print (out, &Context.SourceMgr );
7084
- out << " ]" ;
7085
- break ;
7086
- case RequirementKind::SameType:
7087
- out << " \n " ;
7088
- out << type.getString () << " == " ;
7089
- auto secondType = constraint.get <Type>();
7090
- out << secondType.getString ();
7091
- out << " [" ;
7092
- source->print (out, &Context.SourceMgr );
7093
- out << " ]" ;
7094
- break ;
7095
- }
7096
- });
7097
- out << " \n " ;
7098
-
7099
7102
out << " Potential archetypes:\n " ;
7100
7103
for (auto pa : Impl->PotentialArchetypes ) {
7101
7104
pa->dump (out, &Context.SourceMgr , 2 );
@@ -7119,69 +7122,6 @@ void GenericSignatureBuilder::addGenericSignature(GenericSignature sig) {
7119
7122
addRequirement (reqt, FloatingRequirementSource::forAbstract (), nullptr );
7120
7123
}
7121
7124
7122
- // / Collect the set of requirements placed on the given generic parameters and
7123
- // / their associated types.
7124
- static void collectRequirements (GenericSignatureBuilder &builder,
7125
- TypeArrayView<GenericTypeParamType> params,
7126
- SmallVectorImpl<Requirement> &requirements) {
7127
- builder.enumerateRequirements (
7128
- params,
7129
- [&](RequirementKind kind,
7130
- Type depTy,
7131
- RequirementRHS type,
7132
- const RequirementSource *source) {
7133
- // Filter out derived requirements... except for concrete-type requirements
7134
- // on generic parameters. The exception is due to the canonicalization of
7135
- // generic signatures, which never eliminates generic parameters even when
7136
- // they have been mapped to a concrete type.
7137
- if (source->isDerivedRequirement () &&
7138
- !(kind == RequirementKind::SameType &&
7139
- depTy->is <GenericTypeParamType>() &&
7140
- type.is <Type>()))
7141
- return ;
7142
-
7143
- if (depTy->hasError ())
7144
- return ;
7145
-
7146
- assert (!depTy->findUnresolvedDependentMemberType () &&
7147
- " Unresolved dependent member type in requirements" );
7148
-
7149
- depTy = getSugaredDependentType (depTy, params);
7150
-
7151
- Type repTy;
7152
- if (auto concreteTy = type.dyn_cast <Type>()) {
7153
- // Maybe we were equated to a concrete or dependent type...
7154
- repTy = concreteTy;
7155
-
7156
- // Drop requirements involving concrete types containing
7157
- // unresolved associated types.
7158
- if (repTy->findUnresolvedDependentMemberType ())
7159
- return ;
7160
-
7161
- if (repTy->isTypeParameter ())
7162
- repTy = getSugaredDependentType (repTy, params);
7163
- } else {
7164
- auto layoutConstraint = type.get <LayoutConstraint>();
7165
- requirements.push_back (Requirement (kind, depTy, layoutConstraint));
7166
- return ;
7167
- }
7168
-
7169
- if (repTy->hasError ())
7170
- return ;
7171
-
7172
- requirements.push_back (Requirement (kind, depTy, repTy));
7173
- });
7174
-
7175
- // Sort the subject types in canonical order. This needs to be a stable sort
7176
- // so that the relative order of requirements that have the same subject type
7177
- // is preserved.
7178
- std::stable_sort (requirements.begin (), requirements.end (),
7179
- [](const Requirement &lhs, const Requirement &rhs) {
7180
- return compareDependentTypes (lhs.getFirstType (),
7181
- rhs.getFirstType ()) < 0 ;
7182
- });
7183
- }
7184
-
7185
7125
GenericSignature GenericSignatureBuilder::computeGenericSignature (
7186
7126
bool allowConcreteGenericParams,
7187
7127
bool allowBuilderToMove) && {
@@ -7190,7 +7130,7 @@ GenericSignature GenericSignatureBuilder::computeGenericSignature(
7190
7130
7191
7131
// Collect the requirements placed on the generic parameter types.
7192
7132
SmallVector<Requirement, 4 > requirements;
7193
- collectRequirements (* this , getGenericParams (), requirements);
7133
+ enumerateRequirements ( getGenericParams (), requirements);
7194
7134
7195
7135
// Form the generic signature.
7196
7136
auto sig = GenericSignature::get (getGenericParams (), requirements);
0 commit comments