@@ -626,6 +626,97 @@ Type GenericSignatureImpl::getNonDependentUpperBounds(Type type) const {
626
626
return boundsTy;
627
627
}
628
628
629
+ Type GenericSignatureImpl::getDependentUpperBounds (Type type) const {
630
+ assert (type->isTypeParameter ());
631
+
632
+ llvm::SmallVector<Type, 2 > types;
633
+
634
+ auto &ctx = type->getASTContext ();
635
+
636
+ bool hasExplicitAnyObject = requiresClass (type);
637
+
638
+ // FIXME: If the superclass bound is implied by one of our protocols, we
639
+ // shouldn't add it to the constraint type.
640
+ if (Type superclass = getSuperclassBound (type)) {
641
+ types.push_back (superclass);
642
+ hasExplicitAnyObject = false ;
643
+ }
644
+
645
+ for (auto proto : getRequiredProtocols (type)) {
646
+ if (proto->requiresClass ())
647
+ hasExplicitAnyObject = false ;
648
+
649
+ auto *baseType = proto->getDeclaredInterfaceType ()->castTo <ProtocolType>();
650
+
651
+ auto primaryAssocTypes = proto->getPrimaryAssociatedTypes ();
652
+ if (!primaryAssocTypes.empty ()) {
653
+ SmallVector<Type, 2 > argTypes;
654
+
655
+ // Attempt to recover same-type requirements on primary associated types.
656
+ for (auto *assocType : primaryAssocTypes) {
657
+ // For each primary associated type A of P, compute the reduced type
658
+ // of T.[P]A.
659
+ auto *memberType = DependentMemberType::get (type, assocType);
660
+ auto reducedType = getReducedType (memberType);
661
+
662
+ // If the reduced type is at a lower depth than the root generic
663
+ // parameter of T, then it's constrained.
664
+ bool hasOuterGenericParam = false ;
665
+ bool hasInnerGenericParam = false ;
666
+ reducedType.visit ([&](Type t) {
667
+ if (auto *paramTy = t->getAs <GenericTypeParamType>()) {
668
+ unsigned rootDepth = type->getRootGenericParam ()->getDepth ();
669
+ if (paramTy->getDepth () == rootDepth)
670
+ hasInnerGenericParam = true ;
671
+ else {
672
+ assert (paramTy->getDepth () < rootDepth);
673
+ hasOuterGenericParam = true ;
674
+ }
675
+ }
676
+ });
677
+
678
+ if (hasInnerGenericParam && hasOuterGenericParam) {
679
+ llvm::errs () << " Weird same-type requirements?\n " ;
680
+ llvm::errs () << " Interface type: " << type << " \n " ;
681
+ llvm::errs () << " Member type: " << memberType << " \n " ;
682
+ llvm::errs () << " Reduced member type: " << reducedType << " \n " ;
683
+ llvm::errs () << GenericSignature (this ) << " \n " ;
684
+ abort ();
685
+ }
686
+
687
+ if (!hasInnerGenericParam)
688
+ argTypes.push_back (reducedType);
689
+ }
690
+
691
+ // We should have either constrained all primary associated types,
692
+ // or none of them.
693
+ if (!argTypes.empty ()) {
694
+ if (argTypes.size () != primaryAssocTypes.size ()) {
695
+ llvm::errs () << " Not all primary associated types constrained?\n " ;
696
+ llvm::errs () << " Interface type: " << type << " \n " ;
697
+ llvm::errs () << GenericSignature (this ) << " \n " ;
698
+ abort ();
699
+ }
700
+
701
+ types.push_back (ParameterizedProtocolType::get (ctx, baseType, argTypes));
702
+ continue ;
703
+ }
704
+ }
705
+
706
+ types.push_back (baseType);
707
+ }
708
+
709
+ auto constraint = ProtocolCompositionType::get (
710
+ ctx, types, hasExplicitAnyObject);
711
+
712
+ if (!constraint->isConstraintType ()) {
713
+ assert (constraint->getClassOrBoundGenericClass ());
714
+ return constraint;
715
+ }
716
+
717
+ return ExistentialType::get (constraint);
718
+ }
719
+
629
720
void GenericSignature::Profile (llvm::FoldingSetNodeID &id) const {
630
721
return GenericSignature::Profile (id, getPointer ()->getGenericParams (),
631
722
getPointer ()->getRequirements ());
0 commit comments