@@ -515,23 +515,19 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
515
515
// / Generic types
516
516
// /
517
517
518
- // / Form the interface type of an extension from the raw type and the
519
- // / extension's list of generic parameters.
520
- static Type formExtensionInterfaceType (
521
- ExtensionDecl *ext, Type type,
522
- const GenericParamList *genericParams,
523
- SmallVectorImpl<Requirement> &sameTypeReqs,
524
- bool &mustInferRequirements) {
518
+ // / Collect additional requirements into \p sameTypeReqs.
519
+ static void collectAdditionalExtensionRequirements (
520
+ Type type, SmallVectorImpl<Requirement> &sameTypeReqs) {
525
521
if (type->is <ErrorType>())
526
- return type ;
522
+ return ;
527
523
528
524
// Find the nominal type declaration and its parent type.
529
525
if (type->is <ProtocolCompositionType>())
530
526
type = type->getCanonicalType ();
531
527
532
528
// A parameterized protocol type is not a nominal. Unwrap it to get
533
529
// the underlying nominal, and record a same-type requirement for
534
- // the primary associated type .
530
+ // the primary associated types .
535
531
if (auto *paramProtoTy = type->getAs <ParameterizedProtocolType>()) {
536
532
auto *protoTy = paramProtoTy->getBaseType ();
537
533
type = protoTy;
@@ -544,15 +540,9 @@ static Type formExtensionInterfaceType(
544
540
Type parentType = type->getNominalParent ();
545
541
GenericTypeDecl *genericDecl = type->getAnyGeneric ();
546
542
547
- // Reconstruct the parent, if there is one.
543
+ // Visit the parent type , if there is one.
548
544
if (parentType) {
549
- // Build the nested extension type.
550
- auto parentGenericParams = genericDecl->getGenericParams ()
551
- ? genericParams->getOuterParameters ()
552
- : genericParams;
553
- parentType =
554
- formExtensionInterfaceType (ext, parentType, parentGenericParams,
555
- sameTypeReqs, mustInferRequirements);
545
+ collectAdditionalExtensionRequirements (parentType, sameTypeReqs);
556
546
}
557
547
558
548
// Find the nominal type.
@@ -563,59 +553,26 @@ static Type formExtensionInterfaceType(
563
553
nominal = type->getNominalOrBoundGenericNominal ();
564
554
}
565
555
566
- // Form the result.
567
- Type resultType;
568
- SmallVector<Type, 2 > genericArgs;
569
- if (!nominal->isGeneric () || isa<ProtocolDecl>(nominal)) {
570
- resultType = NominalType::get (nominal, parentType,
571
- nominal->getASTContext ());
572
- } else if (genericParams) {
573
- auto currentBoundType = type->getAs <BoundGenericType>();
574
-
575
- // Form the bound generic type with the type parameters provided.
576
- unsigned gpIndex = 0 ;
577
- for (auto gp : *genericParams) {
578
- SWIFT_DEFER { ++gpIndex; };
579
-
556
+ // If we have a bound generic type, add same-type requirements for each of
557
+ // its generic arguments.
558
+ if (auto currentBoundType = type->getAs <BoundGenericType>()) {
559
+ auto *genericParams = currentBoundType->getDecl ()->getGenericParams ();
560
+ for (unsigned gpIndex : indices (genericParams->getParams ())) {
561
+ auto *gp = genericParams->getParams ()[gpIndex];
580
562
auto gpType = gp->getDeclaredInterfaceType ();
581
- genericArgs.push_back (gpType);
582
563
583
- if (currentBoundType) {
584
- sameTypeReqs.emplace_back (RequirementKind::SameType, gpType,
585
- currentBoundType->getGenericArgs ()[gpIndex]);
586
- }
564
+ sameTypeReqs.emplace_back (RequirementKind::SameType, gpType,
565
+ currentBoundType->getGenericArgs ()[gpIndex]);
587
566
}
588
-
589
- resultType = BoundGenericType::get (nominal, parentType, genericArgs);
590
567
}
591
568
592
- // If we have a typealias, try to form type sugar.
569
+ // If we have a passthrough typealias, add the requirements from its
570
+ // generic signature.
593
571
if (typealias && TypeChecker::isPassThroughTypealias (
594
572
typealias, typealias->getUnderlyingType (), nominal)) {
595
- auto typealiasSig = typealias->getGenericSignature ();
596
- SubstitutionMap subMap;
597
- if (typealiasSig) {
598
- subMap = typealiasSig->getIdentitySubstitutionMap ();
599
-
600
- mustInferRequirements = true ;
601
- }
602
-
603
- resultType = TypeAliasType::get (typealias, parentType, subMap, resultType);
573
+ for (auto req : typealias->getGenericSignature ().getRequirements ())
574
+ sameTypeReqs.push_back (req);
604
575
}
605
-
606
-
607
- return resultType;
608
- }
609
-
610
- // / Retrieve the generic parameter depth of the extended type.
611
- static unsigned getExtendedTypeGenericDepth (ExtensionDecl *ext) {
612
- auto nominal = ext->getSelfNominalTypeDecl ();
613
- if (!nominal) return static_cast <unsigned >(-1 );
614
-
615
- auto sig = nominal->getGenericSignatureOfContext ();
616
- if (!sig) return static_cast <unsigned >(-1 );
617
-
618
- return sig.getGenericParams ().back ()->getDepth ();
619
576
}
620
577
621
578
GenericSignature
@@ -650,7 +607,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
650
607
}
651
608
652
609
bool allowConcreteGenericParams = false ;
653
- const auto *genericParams = GC->getGenericParams ();
610
+ auto *genericParams = GC->getGenericParams ();
654
611
const auto *where = GC->getTrailingWhereClause ();
655
612
656
613
if (genericParams) {
@@ -695,10 +652,12 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
695
652
return GC->getParentForLookup ()->getGenericSignatureOfContext ();
696
653
}
697
654
698
- auto parentSig = GC-> getParentForLookup ()-> getGenericSignatureOfContext () ;
655
+ GenericSignature parentSig;
699
656
SmallVector<TypeLoc, 2 > inferenceSources;
700
657
SmallVector<Requirement, 2 > sameTypeReqs;
701
658
if (auto VD = dyn_cast_or_null<ValueDecl>(GC->getAsDecl ())) {
659
+ parentSig = GC->getParentForLookup ()->getGenericSignatureOfContext ();
660
+
702
661
auto func = dyn_cast<AbstractFunctionDecl>(VD);
703
662
auto subscr = dyn_cast<SubscriptDecl>(VD);
704
663
@@ -753,38 +712,23 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
753
712
}
754
713
}
755
714
} else if (auto *ext = dyn_cast<ExtensionDecl>(GC)) {
756
- // Form the interface type of the extension so we can use it as an inference
757
- // source.
758
- //
759
- // FIXME: Push this into the "get interface type" request.
760
- bool mustInferRequirements = false ;
761
- Type extInterfaceType =
762
- formExtensionInterfaceType (ext, ext->getExtendedType (),
763
- genericParams, sameTypeReqs,
764
- mustInferRequirements);
765
-
766
- auto cannotReuseNominalSignature = [&]() -> bool {
767
- const auto finalDepth = genericParams->getParams ().back ()->getDepth ();
768
- return mustInferRequirements
769
- || !sameTypeReqs.empty ()
770
- || ext->getTrailingWhereClause ()
771
- || (getExtendedTypeGenericDepth (ext) != finalDepth);
772
- };
715
+ parentSig = ext->getExtendedNominal ()->getGenericSignatureOfContext ();
716
+ genericParams = nullptr ;
717
+
718
+ collectAdditionalExtensionRequirements (ext->getExtendedType (), sameTypeReqs);
773
719
774
- // Re-use the signature of the type being extended by default.
775
- if (! cannotReuseNominalSignature ()) {
776
- return ext-> getSelfNominalTypeDecl ()-> getGenericSignatureOfContext () ;
720
+ // Re-use the signature of the type being extended by default.
721
+ if (sameTypeReqs. empty () && !ext-> getTrailingWhereClause ()) {
722
+ return parentSig ;
777
723
}
778
724
779
725
// Allow parameters to be equated with concrete types.
780
726
allowConcreteGenericParams = true ;
781
-
782
- inferenceSources.emplace_back (nullptr , extInterfaceType);
783
727
}
784
728
785
729
auto request = InferredGenericSignatureRequest{
786
730
GC->getParentModule (), parentSig.getPointer (),
787
- GC-> getGenericParams () , WhereClauseOwner (GC),
731
+ genericParams , WhereClauseOwner (GC),
788
732
sameTypeReqs, inferenceSources,
789
733
allowConcreteGenericParams};
790
734
auto sig = evaluateOrDefault (ctx.evaluator , request,
0 commit comments