@@ -468,23 +468,19 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
468468// / Generic types
469469// /
470470
471- // / Form the interface type of an extension from the raw type and the
472- // / extension's list of generic parameters.
473- static Type formExtensionInterfaceType (
474- ExtensionDecl *ext, Type type,
475- const GenericParamList *genericParams,
476- SmallVectorImpl<Requirement> &sameTypeReqs,
477- bool &mustInferRequirements) {
471+ // / Collect additional requirements into \p sameTypeReqs.
472+ static void collectAdditionalExtensionRequirements (
473+ Type type, SmallVectorImpl<Requirement> &sameTypeReqs) {
478474 if (type->is <ErrorType>())
479- return type ;
475+ return ;
480476
481477 // Find the nominal type declaration and its parent type.
482478 if (type->is <ProtocolCompositionType>())
483479 type = type->getCanonicalType ();
484480
485481 // A parameterized protocol type is not a nominal. Unwrap it to get
486482 // the underlying nominal, and record a same-type requirement for
487- // the primary associated type .
483+ // the primary associated types .
488484 if (auto *paramProtoTy = type->getAs <ParameterizedProtocolType>()) {
489485 auto *protoTy = paramProtoTy->getBaseType ();
490486 type = protoTy;
@@ -497,15 +493,9 @@ static Type formExtensionInterfaceType(
497493 Type parentType = type->getNominalParent ();
498494 GenericTypeDecl *genericDecl = type->getAnyGeneric ();
499495
500- // Reconstruct the parent, if there is one.
496+ // Visit the parent type , if there is one.
501497 if (parentType) {
502- // Build the nested extension type.
503- auto parentGenericParams = genericDecl->getGenericParams ()
504- ? genericParams->getOuterParameters ()
505- : genericParams;
506- parentType =
507- formExtensionInterfaceType (ext, parentType, parentGenericParams,
508- sameTypeReqs, mustInferRequirements);
498+ collectAdditionalExtensionRequirements (parentType, sameTypeReqs);
509499 }
510500
511501 // Find the nominal type.
@@ -516,59 +506,26 @@ static Type formExtensionInterfaceType(
516506 nominal = type->getNominalOrBoundGenericNominal ();
517507 }
518508
519- // Form the result.
520- Type resultType;
521- SmallVector<Type, 2 > genericArgs;
522- if (!nominal->isGeneric () || isa<ProtocolDecl>(nominal)) {
523- resultType = NominalType::get (nominal, parentType,
524- nominal->getASTContext ());
525- } else if (genericParams) {
526- auto currentBoundType = type->getAs <BoundGenericType>();
527-
528- // Form the bound generic type with the type parameters provided.
529- unsigned gpIndex = 0 ;
530- for (auto gp : *genericParams) {
531- SWIFT_DEFER { ++gpIndex; };
532-
509+ // If we have a bound generic type, add same-type requirements for each of
510+ // its generic arguments.
511+ if (auto currentBoundType = type->getAs <BoundGenericType>()) {
512+ auto *genericParams = currentBoundType->getDecl ()->getGenericParams ();
513+ for (unsigned gpIndex : indices (genericParams->getParams ())) {
514+ auto *gp = genericParams->getParams ()[gpIndex];
533515 auto gpType = gp->getDeclaredInterfaceType ();
534- genericArgs.push_back (gpType);
535516
536- if (currentBoundType) {
537- sameTypeReqs.emplace_back (RequirementKind::SameType, gpType,
538- currentBoundType->getGenericArgs ()[gpIndex]);
539- }
517+ sameTypeReqs.emplace_back (RequirementKind::SameType, gpType,
518+ currentBoundType->getGenericArgs ()[gpIndex]);
540519 }
541-
542- resultType = BoundGenericType::get (nominal, parentType, genericArgs);
543520 }
544521
545- // If we have a typealias, try to form type sugar.
522+ // If we have a passthrough typealias, add the requirements from its
523+ // generic signature.
546524 if (typealias && TypeChecker::isPassThroughTypealias (
547525 typealias, typealias->getUnderlyingType (), nominal)) {
548- auto typealiasSig = typealias->getGenericSignature ();
549- SubstitutionMap subMap;
550- if (typealiasSig) {
551- subMap = typealiasSig->getIdentitySubstitutionMap ();
552-
553- mustInferRequirements = true ;
554- }
555-
556- resultType = TypeAliasType::get (typealias, parentType, subMap, resultType);
526+ for (auto req : typealias->getGenericSignature ().getRequirements ())
527+ sameTypeReqs.push_back (req);
557528 }
558-
559-
560- return resultType;
561- }
562-
563- // / Retrieve the generic parameter depth of the extended type.
564- static unsigned getExtendedTypeGenericDepth (ExtensionDecl *ext) {
565- auto nominal = ext->getSelfNominalTypeDecl ();
566- if (!nominal) return static_cast <unsigned >(-1 );
567-
568- auto sig = nominal->getGenericSignatureOfContext ();
569- if (!sig) return static_cast <unsigned >(-1 );
570-
571- return sig.getGenericParams ().back ()->getDepth ();
572529}
573530
574531GenericSignature
@@ -605,7 +562,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
605562 }
606563
607564 bool allowConcreteGenericParams = false ;
608- const auto *genericParams = GC->getGenericParams ();
565+ auto *genericParams = GC->getGenericParams ();
609566 const auto *where = GC->getTrailingWhereClause ();
610567
611568 if (genericParams) {
@@ -650,10 +607,12 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
650607 return GC->getParentForLookup ()->getGenericSignatureOfContext ();
651608 }
652609
653- auto parentSig = GC-> getParentForLookup ()-> getGenericSignatureOfContext () ;
610+ GenericSignature parentSig;
654611 SmallVector<TypeLoc, 2 > inferenceSources;
655612 SmallVector<Requirement, 2 > sameTypeReqs;
656613 if (auto VD = dyn_cast_or_null<ValueDecl>(GC->getAsDecl ())) {
614+ parentSig = GC->getParentForLookup ()->getGenericSignatureOfContext ();
615+
657616 auto func = dyn_cast<AbstractFunctionDecl>(VD);
658617 auto subscr = dyn_cast<SubscriptDecl>(VD);
659618
@@ -708,38 +667,23 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
708667 }
709668 }
710669 } else if (auto *ext = dyn_cast<ExtensionDecl>(GC)) {
711- // Form the interface type of the extension so we can use it as an inference
712- // source.
713- //
714- // FIXME: Push this into the "get interface type" request.
715- bool mustInferRequirements = false ;
716- Type extInterfaceType =
717- formExtensionInterfaceType (ext, ext->getExtendedType (),
718- genericParams, sameTypeReqs,
719- mustInferRequirements);
720-
721- auto cannotReuseNominalSignature = [&]() -> bool {
722- const auto finalDepth = genericParams->getParams ().back ()->getDepth ();
723- return mustInferRequirements
724- || !sameTypeReqs.empty ()
725- || ext->getTrailingWhereClause ()
726- || (getExtendedTypeGenericDepth (ext) != finalDepth);
727- };
670+ parentSig = ext->getExtendedNominal ()->getGenericSignatureOfContext ();
671+ genericParams = nullptr ;
672+
673+ collectAdditionalExtensionRequirements (ext->getExtendedType (), sameTypeReqs);
728674
729- // Re-use the signature of the type being extended by default.
730- if (! cannotReuseNominalSignature ()) {
731- return ext-> getSelfNominalTypeDecl ()-> getGenericSignatureOfContext () ;
675+ // Re-use the signature of the type being extended by default.
676+ if (sameTypeReqs. empty () && !ext-> getTrailingWhereClause ()) {
677+ return parentSig ;
732678 }
733679
734680 // Allow parameters to be equated with concrete types.
735681 allowConcreteGenericParams = true ;
736-
737- inferenceSources.emplace_back (nullptr , extInterfaceType);
738682 }
739683
740684 auto request = InferredGenericSignatureRequest{
741685 parentSig.getPointer (),
742- GC-> getGenericParams () , WhereClauseOwner (GC),
686+ genericParams , WhereClauseOwner (GC),
743687 sameTypeReqs, inferenceSources,
744688 allowConcreteGenericParams};
745689 auto sig = evaluateOrDefault (ctx.evaluator , request,
0 commit comments