@@ -501,24 +501,38 @@ void GenericSignatureBuilder::PotentialArchetype::resolveAssociatedType(
501501 --builder.Impl ->NumUnresolvedNestedTypes ;
502502}
503503
504- const RequirementSource *
504+ Optional<std::pair<Type, const RequirementSource *>>
505505PotentialArchetype::findAnyConcreteTypeSourceAsWritten () const {
506- // If we have a concrete type source, use that.
507- if (ConcreteTypeSource && ConcreteTypeSource->getLoc ().isValid ())
508- return ConcreteTypeSource;
506+ using Result = std::pair<Type, const RequirementSource *>;
507+
508+ // Local function to look for a source in the given potential archetype.
509+ auto lookInPA = [](const PotentialArchetype *pa) -> Optional<Result> {
510+ for (unsigned i : indices (pa->concreteTypeSources )) {
511+ auto source = pa->concreteTypeSources [i];
512+ if (source->getLoc ().isValid ())
513+ return Result (pa->concreteTypes [i], source);
514+ }
515+
516+ return None;
517+ };
518+
519+ // If we have a concrete type source with location information, use that.
520+ if (auto result = lookInPA (this ))
521+ return result;
509522
510523 // If we don't have a concrete type, there's no source.
511524 auto rep = getRepresentative ();
512- if (!rep->isConcreteType ()) return nullptr ;
525+ if (!rep->isConcreteType ()) return None ;
513526
514527 // Otherwise, go look for the source.
515528 for (auto pa : rep->getEquivalenceClassMembers ()) {
516- if (pa->ConcreteTypeSource &&
517- pa->ConcreteTypeSource ->getLoc ().isValid ())
518- return pa->ConcreteTypeSource ;
529+ if (pa != this ) {
530+ if (auto result = lookInPA (pa))
531+ return result;
532+ }
519533 }
520534
521- return nullptr ;
535+ return None ;
522536}
523537
524538bool GenericSignatureBuilder::updateRequirementSource (
@@ -589,7 +603,7 @@ struct GenericSignatureBuilder::ResolvedType {
589603
590604 static ResolvedType forNewTypeAlias (PotentialArchetype *pa) {
591605 assert (pa->getParent () && pa->getTypeAliasDecl () &&
592- pa->ConcreteType . isNull () &&
606+ pa->concreteTypes . empty () &&
593607 pa->getEquivalenceClassMembers ().size () == 1 &&
594608 " not a new typealias" );
595609 return ResolvedType (pa);
@@ -1340,17 +1354,18 @@ void GenericSignatureBuilder::PotentialArchetype::dump(llvm::raw_ostream &Out,
13401354 }
13411355
13421356 // Print concrete type.
1343- if (ConcreteType) {
1357+ for (unsigned i : indices (concreteTypes)) {
1358+ auto concreteType = concreteTypes[i];
13441359 Out << " == " ;
1345- ConcreteType .print (Out);
1346- if (ConcreteTypeSource) {
1347- Out << " " ;
1348- if (!ConcreteTypeSource-> isDerivedRequirement ())
1349- Out << " * " ;
1350- Out << " [ " ;
1351- ConcreteTypeSource-> print ( Out, SrcMgr) ;
1352- Out << " ] " ;
1353- }
1360+ concreteType .print (Out);
1361+
1362+ auto concreteTypeSource = concreteTypeSources[i] ;
1363+ Out << " " ;
1364+ if (!concreteTypeSource-> isDerivedRequirement ())
1365+ Out << " * " ;
1366+ Out << " [ " ;
1367+ concreteTypeSource-> print ( Out, SrcMgr) ;
1368+ Out << " ] " ;
13541369 }
13551370
13561371 // Print requirements.
@@ -1673,10 +1688,10 @@ bool GenericSignatureBuilder::addSuperclassRequirement(PotentialArchetype *T,
16731688 Type concrete = T->getConcreteType ();
16741689 if (!Superclass->isExactSuperclassOf (concrete, getLazyResolver ())) {
16751690 if (auto source = T->findAnyConcreteTypeSourceAsWritten ()) {
1676- Diags.diagnose (source->getLoc (), diag::type_does_not_inherit,
1691+ Diags.diagnose (source->second -> getLoc (), diag::type_does_not_inherit,
16771692 T->getDependentType (/* FIXME:*/ { },
16781693 /* allowUnresolved=*/ true ),
1679- concrete , Superclass)
1694+ source-> first , Superclass)
16801695 .highlight (Source->getLoc ());
16811696 }
16821697 return true ;
@@ -1912,11 +1927,8 @@ bool GenericSignatureBuilder::addSameTypeRequirementToConcrete(
19121927 Type Concrete,
19131928 const RequirementSource *Source) {
19141929 // Record the concrete type and its source.
1915- if (!T->ConcreteType ) {
1916- // FIXME: Always record this.
1917- T->ConcreteType = Concrete;
1918- T->ConcreteTypeSource = Source;
1919- }
1930+ T->concreteTypes .push_back (Concrete);
1931+ T->concreteTypeSources .push_back (Source);
19201932
19211933 // If we've already been bound to a type, match that type.
19221934 if (auto oldConcrete = T->getConcreteType ()) {
@@ -2540,11 +2552,11 @@ GenericSignatureBuilder::finalize(SourceLoc loc,
25402552 // Check for recursive same-type bindings.
25412553 if (isRecursiveConcreteType (archetype, /* isSuperclass=*/ false )) {
25422554 if (auto source = archetype->findAnyConcreteTypeSourceAsWritten ()) {
2543- Diags.diagnose (source->getLoc (),
2555+ Diags.diagnose (source->second -> getLoc (),
25442556 diag::recursive_same_type_constraint,
25452557 archetype->getDependentType (genericParams,
25462558 /* allowUnresolved=*/ true ),
2547- archetype-> getConcreteType () );
2559+ source-> first );
25482560 }
25492561
25502562 archetype->RecursiveConcreteType = true ;
@@ -2590,7 +2602,7 @@ GenericSignatureBuilder::finalize(SourceLoc loc,
25902602 // because then we don't actually have a parameter.
25912603 if (rep->getConcreteType ()) {
25922604 if (auto source = rep->findAnyConcreteTypeSourceAsWritten ())
2593- Diags.diagnose (source->getLoc (),
2605+ Diags.diagnose (source->second -> getLoc (),
25942606 diag::requires_generic_param_made_equal_to_concrete,
25952607 rep->getDependentType (genericParams,
25962608 /* allowUnresolved=*/ true ));
@@ -2718,46 +2730,49 @@ void GenericSignatureBuilder::checkRedundantConcreteTypeConstraints(
27182730 // Gather the concrete constraints within this equivalence class.
27192731 SmallVector<ConcreteConstraint, 4 > concreteConstraints;
27202732 for (auto pa : representative->getEquivalenceClassMembers ()) {
2721- auto source = pa->getConcreteTypeSourceAsWritten ();
2722- if (!source) continue ;
2723-
2724- // Save this constraint.
2725- auto constraint = ConcreteConstraint{pa, pa->ConcreteType , source};
2726- concreteConstraints.push_back (constraint);
2727-
2728- // Check whether this constraint is better than the best we've seen so far
2729- // at being the representative constraint against which others will be
2730- // compared.
2731- if (!representativeConstraint) {
2732- representativeConstraint = constraint;
2733- continue ;
2734- }
2735-
2736- // We prefer derived constraints to non-derived constraints.
2737- bool thisIsDerived = source->isDerivedRequirement ();
2738- bool representativeIsDerived =
2739- representativeConstraint->source ->isDerivedRequirement ();
2740- if (thisIsDerived != representativeIsDerived) {
2741- if (thisIsDerived)
2733+ auto types = pa->getConcreteTypesAsWritten ();
2734+ auto sources = pa->getConcreteTypeSourcesAsWritten ();
2735+ for (unsigned i : indices (types)) {
2736+ auto source = sources[i];
2737+
2738+ // Save this constraint.
2739+ auto constraint = ConcreteConstraint{pa, types[i], source};
2740+ concreteConstraints.push_back (constraint);
2741+
2742+ // Check whether this constraint is better than the best we've seen so far
2743+ // at being the representative constraint against which others will be
2744+ // compared.
2745+ if (!representativeConstraint) {
27422746 representativeConstraint = constraint;
2747+ continue ;
2748+ }
27432749
2744- continue ;
2745- }
2750+ // We prefer derived constraints to non-derived constraints.
2751+ bool thisIsDerived = source->isDerivedRequirement ();
2752+ bool representativeIsDerived =
2753+ representativeConstraint->source ->isDerivedRequirement ();
2754+ if (thisIsDerived != representativeIsDerived) {
2755+ if (thisIsDerived)
2756+ representativeConstraint = constraint;
27462757
2747- // We prefer constraints with locations to constraints without locations.
2748- bool thisHasValidSourceLoc = source->getLoc ().isValid ();
2749- bool representativeHasValidSourceLoc =
2750- representativeConstraint->source ->getLoc ().isValid ();
2751- if (thisHasValidSourceLoc != representativeHasValidSourceLoc) {
2752- if (thisHasValidSourceLoc)
2753- representativeConstraint = constraint;
2758+ continue ;
2759+ }
27542760
2755- continue ;
2756- }
2761+ // We prefer constraints with locations to constraints without locations.
2762+ bool thisHasValidSourceLoc = source->getLoc ().isValid ();
2763+ bool representativeHasValidSourceLoc =
2764+ representativeConstraint->source ->getLoc ().isValid ();
2765+ if (thisHasValidSourceLoc != representativeHasValidSourceLoc) {
2766+ if (thisHasValidSourceLoc)
2767+ representativeConstraint = constraint;
27572768
2758- // Otherwise, order via the constraint itself.
2759- if (constraint < *representativeConstraint)
2760- representativeConstraint = constraint;
2769+ continue ;
2770+ }
2771+
2772+ // Otherwise, order via the constraint itself.
2773+ if (constraint < *representativeConstraint)
2774+ representativeConstraint = constraint;
2775+ }
27612776 }
27622777
27632778 // Sort the concrete constraints, so we get deterministic ordering of
@@ -2935,20 +2950,25 @@ static SmallVector<SameTypeComponent, 2> getSameTypeComponents(
29352950
29362951 // Find the best anchor and concrete type source for this component.
29372952 PotentialArchetype *anchor = component[0 ];
2938- auto bestConcreteTypeSource = anchor->getConcreteTypeSourceAsWritten ();
2953+ const RequirementSource *bestConcreteTypeSource = nullptr ;
2954+ auto considerNewSource = [&](const RequirementSource *source) {
2955+ if (!bestConcreteTypeSource ||
2956+ source->compare (bestConcreteTypeSource) < 0 )
2957+ bestConcreteTypeSource = source;
2958+ };
29392959
2940- for (auto componentPA : ArrayRef<PotentialArchetype *>(component).slice (1 )){
2960+ if (!anchor->getConcreteTypeSourcesAsWritten ().empty ())
2961+ bestConcreteTypeSource = anchor->getConcreteTypeSourcesAsWritten ()[0 ];
2962+
2963+ for (auto componentPA : ArrayRef<PotentialArchetype *>(component)) {
29412964 // Update the anchor.
29422965 if (compareDependentTypes (&componentPA, &anchor) < 0 )
29432966 anchor = componentPA;
29442967
29452968 // If this potential archetype has a better concrete type source than
29462969 // the best we've seen, take it.
2947- if (auto concreteSource = componentPA->getConcreteTypeSourceAsWritten ()) {
2948- if (!bestConcreteTypeSource ||
2949- concreteSource->compare (bestConcreteTypeSource) < 0 )
2950- bestConcreteTypeSource = concreteSource;
2951- }
2970+ for (auto source: componentPA->getConcreteTypeSourcesAsWritten ())
2971+ considerNewSource (source);
29522972 }
29532973
29542974 // Record the anchor.
0 commit comments