@@ -698,7 +698,7 @@ struct GenericSignatureBuilder::Implementation {
698698 bool HadAnyError = false ;
699699
700700 // / All explicit non-same type requirements that were added to the builder.
701- SmallVector <ExplicitRequirement, 2 > ExplicitRequirements;
701+ SmallSetVector <ExplicitRequirement, 2 > ExplicitRequirements;
702702
703703 // / All explicit same-type requirements that were added to the builder.
704704 SmallVector<Requirement, 2 > ExplicitSameTypeRequirements;
@@ -2607,21 +2607,22 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
26072607 concreteSource = concreteSource->viaConcrete (*this , concrete);
26082608 } else {
26092609 concreteSource = concreteSource->viaConcrete (*this , conformance);
2610- equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
2611-
2612- // Only infer conditional requirements from explicit sources.
2613- bool hasExplicitSource = llvm::any_of (
2614- equivClass->concreteTypeConstraints ,
2615- [](const ConcreteConstraint &constraint) {
2616- return (!constraint.source ->isDerivedRequirement () &&
2617- constraint.source ->getLoc ().isValid ());
2618- });
2610+ }
26192611
2620- if (hasExplicitSource) {
2621- if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2622- concreteSource->getLoc ()))
2623- return nullptr ;
2624- }
2612+ equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
2613+
2614+ // Only infer conditional requirements from explicit sources.
2615+ bool hasExplicitSource = llvm::any_of (
2616+ equivClass->concreteTypeConstraints ,
2617+ [](const ConcreteConstraint &constraint) {
2618+ return (!constraint.source ->isDerivedRequirement () &&
2619+ constraint.source ->getLoc ().isValid ());
2620+ });
2621+
2622+ if (hasExplicitSource) {
2623+ if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2624+ concreteSource->getLoc ()))
2625+ return nullptr ;
26252626 }
26262627
26272628 return concreteSource;
@@ -4507,8 +4508,9 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
45074508 auto resolvedSource = source.getSource (*this , type);
45084509
45094510 if (!resolvedSource->isDerivedRequirement ()) {
4510- Impl->ExplicitRequirements .emplace_back (RequirementKind::Conformance,
4511- resolvedSource, proto);
4511+ Impl->ExplicitRequirements .insert (
4512+ ExplicitRequirement (RequirementKind::Conformance,
4513+ resolvedSource, proto));
45124514 }
45134515
45144516 // Add the conformance requirement, bailing out earlier if we've already
@@ -4529,8 +4531,9 @@ ConstraintResult GenericSignatureBuilder::addLayoutRequirementDirect(
45294531 auto resolvedSource = source.getSource (*this , type);
45304532
45314533 if (!resolvedSource->isDerivedRequirement ()) {
4532- Impl->ExplicitRequirements .emplace_back (RequirementKind::Layout,
4533- resolvedSource, layout);
4534+ Impl->ExplicitRequirements .insert (
4535+ ExplicitRequirement (RequirementKind::Layout,
4536+ resolvedSource, layout));
45344537 }
45354538
45364539 auto equivClass = type.getEquivalenceClass (*this );
@@ -4670,8 +4673,9 @@ ConstraintResult GenericSignatureBuilder::addSuperclassRequirementDirect(
46704673 auto resolvedSource = source.getSource (*this , type);
46714674
46724675 if (!resolvedSource->isDerivedRequirement ()) {
4673- Impl->ExplicitRequirements .emplace_back (RequirementKind::Superclass,
4674- resolvedSource, superclass);
4676+ Impl->ExplicitRequirements .insert (
4677+ ExplicitRequirement (RequirementKind::Superclass,
4678+ resolvedSource, superclass));
46754679 }
46764680
46774681 // Record the constraint.
@@ -6466,14 +6470,16 @@ GenericSignatureBuilder::finalize(TypeArrayView<GenericTypeParamType> genericPar
64666470 checkLayoutConstraints (genericParams, &equivClass);
64676471 };
64686472
6469- // FIXME: Expand all conformance requirements. This is expensive :(
6470- for (auto &equivClass : Impl->EquivalenceClasses ) {
6473+ if (!Impl->ExplicitSameTypeRequirements .empty ()) {
6474+ // FIXME: Expand all conformance requirements. This is expensive :(
6475+ for (auto &equivClass : Impl->EquivalenceClasses ) {
64716476 expandSameTypeConstraints (*this , &equivClass);
6472- }
6477+ }
64736478
6474- // Check same-type constraints.
6475- for (auto &equivClass : Impl->EquivalenceClasses ) {
6476- checkSameTypeConstraints (genericParams, &equivClass);
6479+ // Check same-type constraints.
6480+ for (auto &equivClass : Impl->EquivalenceClasses ) {
6481+ checkSameTypeConstraints (genericParams, &equivClass);
6482+ }
64776483 }
64786484
64796485 // Check for generic parameters which have been made concrete or equated
@@ -7977,26 +7983,6 @@ bool GenericSignatureBuilder::isRedundantExplicitRequirement(
79777983 return (redundantReqs.find (req) != redundantReqs.end ());
79787984}
79797985
7980- namespace {
7981- template <typename T>
7982- bool hasNonRedundantRequirementSource (ArrayRef<Constraint<T>> constraints,
7983- RequirementKind kind,
7984- GenericSignatureBuilder &builder) {
7985- for (auto constraint : constraints) {
7986- if (constraint.source ->isDerivedRequirement ())
7987- continue ;
7988-
7989- auto req = ExplicitRequirement::fromExplicitConstraint (kind, constraint);
7990- if (builder.isRedundantExplicitRequirement (req))
7991- continue ;
7992-
7993- return true ;
7994- }
7995-
7996- return false ;
7997- }
7998- } // end anonymous namespace
7999-
80007986static Optional<Requirement> createRequirement (RequirementKind kind,
80017987 Type depTy,
80027988 RequirementRHS rhs,
@@ -8075,116 +8061,89 @@ void GenericSignatureBuilder::enumerateRequirements(
80758061 requirements.push_back (*req);
80768062 };
80778063
8078- // Collect all of the subject types that will be involved in constraints.
8079- for (auto &equivClass : Impl->EquivalenceClasses ) {
8080- if (equivClass.derivedSameTypeComponents .empty ()) {
8081- checkSameTypeConstraints (genericParams, &equivClass);
8082- }
8083-
8084- for (unsigned i : indices (equivClass.derivedSameTypeComponents )) {
8085- // Dig out the subject type and its corresponding component.
8086- auto &component = equivClass.derivedSameTypeComponents [i];
8087- Type subjectType = component.type ;
8088-
8089- assert (!subjectType->hasError ());
8090- assert (!subjectType->findUnresolvedDependentMemberType ());
8064+ // Collect all non-same type requirements.
8065+ for (auto &req : Impl->ExplicitRequirements ) {
8066+ if (isRedundantExplicitRequirement (req))
8067+ continue ;
80918068
8092- // If this equivalence class is bound to a concrete type, equate the
8093- // anchor with a concrete type.
8094- if (Type concreteType = equivClass.concreteType ) {
8095- concreteType = getCanonicalTypeInContext (concreteType, genericParams);
8069+ auto depTy = getCanonicalTypeInContext (
8070+ req.getSource ()->getStoredType (), { });
80968071
8097- // If the parent of this anchor is also a concrete type, don't
8098- // create a requirement.
8099- if (!subjectType->is <GenericTypeParamType>() &&
8100- maybeResolveEquivalenceClass (
8101- subjectType->castTo <DependentMemberType>()->getBase (),
8102- ArchetypeResolutionKind::WellFormed,
8103- /* wantExactPotentialArchetype=*/ false )
8104- .getEquivalenceClass (*this )->concreteType )
8105- continue ;
8072+ // FIXME: This should be an assert once we ensure that concrete
8073+ // same-type requirements always mark other requirements on the
8074+ // same subject type as redundant or conflicting.
8075+ if (!depTy->isTypeParameter ())
8076+ continue ;
81068077
8107- // Drop recursive and invalid concrete-type constraints.
8108- if (equivClass. recursiveConcreteType ||
8109- equivClass. invalidConcreteType )
8110- continue ;
8078+ auto rhs = req. getRHS ();
8079+ if ( auto constraintType = rhs. dyn_cast <Type>()) {
8080+ rhs = getCanonicalTypeInContext (constraintType, genericParams);
8081+ }
81118082
8112- // Filter out derived requirements... except for concrete-type
8113- // requirements on generic parameters. The exception is due to
8114- // the canonicalization of generic signatures, which never
8115- // eliminates generic parameters even when they have been
8116- // mapped to a concrete type.
8117- if (subjectType->is <GenericTypeParamType>() ||
8118- component.concreteTypeSource == nullptr ||
8119- !component.concreteTypeSource ->isDerivedRequirement ()) {
8120- recordRequirement (RequirementKind::SameType,
8121- subjectType, concreteType);
8122- }
8123- continue ;
8124- }
8083+ recordRequirement (req.getKind (), depTy, rhs);
8084+ }
81258085
8126- std::function<void ()> deferredSameTypeRequirement;
8127-
8128- // If we're at the last anchor in the component, do nothing;
8129- if (i + 1 != equivClass.derivedSameTypeComponents .size ()) {
8130- // Form a same-type constraint from this anchor within the component
8131- // to the next.
8132- // FIXME: Distinguish between explicit and inferred here?
8133- auto &nextComponent = equivClass.derivedSameTypeComponents [i + 1 ];
8134- Type otherSubjectType = nextComponent.type ;
8135- deferredSameTypeRequirement =
8136- [&recordRequirement, subjectType, otherSubjectType] {
8137- recordRequirement (RequirementKind::SameType,
8138- subjectType, otherSubjectType);
8139- };
8086+ // Collect all same type requirements.
8087+ if (!Impl->ExplicitSameTypeRequirements .empty ()) {
8088+ for (auto &equivClass : Impl->EquivalenceClasses ) {
8089+ if (equivClass.derivedSameTypeComponents .empty ()) {
8090+ checkSameTypeConstraints (genericParams, &equivClass);
81408091 }
81418092
8142- SWIFT_DEFER {
8143- if (deferredSameTypeRequirement) deferredSameTypeRequirement ();
8144- };
8145-
8146- // If this is not the first component anchor in its equivalence class,
8147- // we're done.
8148- if (i > 0 )
8149- continue ;
8150-
8151- // If we have a superclass, produce a superclass requirement
8152- if (auto superclass = equivClass.superclass ) {
8153- superclass = getCanonicalTypeInContext (superclass, genericParams);
8093+ for (unsigned i : indices (equivClass.derivedSameTypeComponents )) {
8094+ // Dig out the subject type and its corresponding component.
8095+ auto &component = equivClass.derivedSameTypeComponents [i];
8096+ Type subjectType = component.type ;
8097+
8098+ assert (!subjectType->hasError ());
8099+ assert (!subjectType->findUnresolvedDependentMemberType ());
8100+
8101+ // If this equivalence class is bound to a concrete type, equate the
8102+ // anchor with a concrete type.
8103+ if (Type concreteType = equivClass.concreteType ) {
8104+ concreteType = getCanonicalTypeInContext (concreteType, genericParams);
8105+
8106+ // If the parent of this anchor is also a concrete type, don't
8107+ // create a requirement.
8108+ if (!subjectType->is <GenericTypeParamType>() &&
8109+ maybeResolveEquivalenceClass (
8110+ subjectType->castTo <DependentMemberType>()->getBase (),
8111+ ArchetypeResolutionKind::WellFormed,
8112+ /* wantExactPotentialArchetype=*/ false )
8113+ .getEquivalenceClass (*this )->concreteType )
8114+ continue ;
81548115
8155- if (!equivClass.recursiveSuperclassType &&
8156- hasNonRedundantRequirementSource<Type>(
8157- equivClass.superclassConstraints ,
8158- RequirementKind::Superclass, *this )) {
8159- recordRequirement (RequirementKind::Superclass,
8160- subjectType, superclass);
8161- }
8162- }
8116+ // Drop recursive and invalid concrete-type constraints.
8117+ if (equivClass.recursiveConcreteType ||
8118+ equivClass.invalidConcreteType )
8119+ continue ;
81638120
8164- // If we have a layout constraint, produce a layout requirement.
8165- if (equivClass.layout ) {
8166- if (hasNonRedundantRequirementSource<LayoutConstraint>(
8167- equivClass.layoutConstraints ,
8168- RequirementKind::Layout, *this )) {
8169- recordRequirement (RequirementKind::Layout,
8170- subjectType, equivClass.layout );
8121+ // Filter out derived requirements... except for concrete-type
8122+ // requirements on generic parameters. The exception is due to
8123+ // the canonicalization of generic signatures, which never
8124+ // eliminates generic parameters even when they have been
8125+ // mapped to a concrete type.
8126+ if (subjectType->is <GenericTypeParamType>() ||
8127+ component.concreteTypeSource == nullptr ||
8128+ !component.concreteTypeSource ->isDerivedRequirement ()) {
8129+ recordRequirement (RequirementKind::SameType,
8130+ subjectType, concreteType);
8131+ }
8132+ continue ;
81718133 }
8172- }
81738134
8174- // Enumerate conformance requirements.
8175- SmallVector<ProtocolDecl *, 4 > protocols;
8135+ // If we're at the last anchor in the component, do nothing;
8136+ if (i + 1 != equivClass.derivedSameTypeComponents .size ()) {
8137+ // Form a same-type constraint from this anchor within the component
8138+ // to the next.
8139+ // FIXME: Distinguish between explicit and inferred here?
8140+ auto &nextComponent = equivClass.derivedSameTypeComponents [i + 1 ];
8141+ Type otherSubjectType = nextComponent.type ;
81768142
8177- for (const auto &conforms : equivClass.conformsTo ) {
8178- if (hasNonRedundantRequirementSource<ProtocolDecl *>(
8179- conforms.second , RequirementKind::Conformance, *this )) {
8180- protocols.push_back (conforms.first );
8143+ recordRequirement (RequirementKind::SameType,
8144+ subjectType, otherSubjectType);
81818145 }
81828146 }
8183-
8184- // Enumerate the conformance requirements.
8185- for (auto proto : protocols) {
8186- recordRequirement (RequirementKind::Conformance, subjectType, proto);
8187- }
81888147 }
81898148 }
81908149
@@ -8310,6 +8269,14 @@ static void checkGenericSignature(CanGenericSignature canSig,
83108269 }
83118270 }
83128271
8272+ // If we have a concrete same-type requirement, we shouldn't have any
8273+ // other requirements on the same type.
8274+ if (reqt.getKind () == RequirementKind::SameType &&
8275+ !reqt.getSecondType ()->isTypeParameter ()) {
8276+ assert (compareLHS < 0 &&
8277+ " Concrete subject type should not have any other requirements" );
8278+ }
8279+
83138280 assert (compareRequirements (&prevReqt, &reqt) < 0 &&
83148281 " Out-of-order requirements" );
83158282 }
0 commit comments