@@ -468,23 +468,19 @@ void TypeChecker::checkReferencedGenericParams(GenericContext *dc) {
468
468
// / Generic types
469
469
// /
470
470
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) {
478
474
if (type->is <ErrorType>())
479
- return type ;
475
+ return ;
480
476
481
477
// Find the nominal type declaration and its parent type.
482
478
if (type->is <ProtocolCompositionType>())
483
479
type = type->getCanonicalType ();
484
480
485
481
// A parameterized protocol type is not a nominal. Unwrap it to get
486
482
// the underlying nominal, and record a same-type requirement for
487
- // the primary associated type .
483
+ // the primary associated types .
488
484
if (auto *paramProtoTy = type->getAs <ParameterizedProtocolType>()) {
489
485
auto *protoTy = paramProtoTy->getBaseType ();
490
486
type = protoTy;
@@ -497,15 +493,9 @@ static Type formExtensionInterfaceType(
497
493
Type parentType = type->getNominalParent ();
498
494
GenericTypeDecl *genericDecl = type->getAnyGeneric ();
499
495
500
- // Reconstruct the parent, if there is one.
496
+ // Visit the parent type , if there is one.
501
497
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);
509
499
}
510
500
511
501
// Find the nominal type.
@@ -516,59 +506,26 @@ static Type formExtensionInterfaceType(
516
506
nominal = type->getNominalOrBoundGenericNominal ();
517
507
}
518
508
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];
533
515
auto gpType = gp->getDeclaredInterfaceType ();
534
- genericArgs.push_back (gpType);
535
516
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]);
540
519
}
541
-
542
- resultType = BoundGenericType::get (nominal, parentType, genericArgs);
543
520
}
544
521
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.
546
524
if (typealias && TypeChecker::isPassThroughTypealias (
547
525
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);
557
528
}
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 ();
572
529
}
573
530
574
531
GenericSignature
@@ -605,7 +562,7 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
605
562
}
606
563
607
564
bool allowConcreteGenericParams = false ;
608
- const auto *genericParams = GC->getGenericParams ();
565
+ auto *genericParams = GC->getGenericParams ();
609
566
const auto *where = GC->getTrailingWhereClause ();
610
567
611
568
if (genericParams) {
@@ -650,10 +607,12 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
650
607
return GC->getParentForLookup ()->getGenericSignatureOfContext ();
651
608
}
652
609
653
- auto parentSig = GC-> getParentForLookup ()-> getGenericSignatureOfContext () ;
610
+ GenericSignature parentSig;
654
611
SmallVector<TypeLoc, 2 > inferenceSources;
655
612
SmallVector<Requirement, 2 > sameTypeReqs;
656
613
if (auto VD = dyn_cast_or_null<ValueDecl>(GC->getAsDecl ())) {
614
+ parentSig = GC->getParentForLookup ()->getGenericSignatureOfContext ();
615
+
657
616
auto func = dyn_cast<AbstractFunctionDecl>(VD);
658
617
auto subscr = dyn_cast<SubscriptDecl>(VD);
659
618
@@ -708,38 +667,23 @@ GenericSignatureRequest::evaluate(Evaluator &evaluator,
708
667
}
709
668
}
710
669
} 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);
728
674
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 ;
732
678
}
733
679
734
680
// Allow parameters to be equated with concrete types.
735
681
allowConcreteGenericParams = true ;
736
-
737
- inferenceSources.emplace_back (nullptr , extInterfaceType);
738
682
}
739
683
740
684
auto request = InferredGenericSignatureRequest{
741
685
parentSig.getPointer (),
742
- GC-> getGenericParams () , WhereClauseOwner (GC),
686
+ genericParams , WhereClauseOwner (GC),
743
687
sameTypeReqs, inferenceSources,
744
688
allowConcreteGenericParams};
745
689
auto sig = evaluateOrDefault (ctx.evaluator , request,
0 commit comments