@@ -2582,6 +2582,15 @@ bool AssociatedTypeInference::checkConstrainedExtension(ExtensionDecl *ext) {
25822582 llvm_unreachable (" unhandled result" );
25832583}
25842584
2585+ static bool containsConcreteDependentMemberType (Type ty) {
2586+ return ty.findIf ([](Type t) -> bool {
2587+ if (auto *dmt = t->getAs <DependentMemberType>())
2588+ return !dmt->isTypeParameter ();
2589+
2590+ return false ;
2591+ });
2592+ }
2593+
25852594AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses (
25862595 ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes, unsigned reqDepth) {
25872596 if (unresolvedAssocTypes.empty ()) {
@@ -2709,15 +2718,15 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
27092718 llvm::SmallPtrSet<AssociatedTypeDecl *, 4 > circularityCheck;
27102719 circularityCheck.insert (assocType);
27112720
2712- std::function<Type (Type)> substCurrentTypeWitnesses;
2713- substCurrentTypeWitnesses = [&](Type ty) -> Type {
2721+ std::function<llvm::Optional< Type> (Type)> substCurrentTypeWitnesses;
2722+ substCurrentTypeWitnesses = [&](Type ty) -> llvm::Optional< Type> {
27142723 auto *const dmt = ty->getAs <DependentMemberType>();
27152724 if (!dmt) {
2716- return ty ;
2725+ return llvm::None ;
27172726 }
27182727
27192728 const auto substBase =
2720- dmt->getBase ().transform (substCurrentTypeWitnesses);
2729+ dmt->getBase ().transformRec (substCurrentTypeWitnesses);
27212730 if (!substBase) {
27222731 return nullptr ;
27232732 }
@@ -2726,9 +2735,16 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
27262735 // need to look up a tentative type witness. Otherwise, just substitute
27272736 // the base.
27282737 if (substBase->getAnyNominal () != dc->getSelfNominalTypeDecl ()) {
2729- return dmt->substBaseType (substBase,
2730- LookUpConformanceInModule (dc->getParentModule ()),
2731- substOptions);
2738+ auto substTy = dmt->substBaseType (
2739+ substBase,
2740+ LookUpConformanceInModule (dc->getParentModule ()),
2741+ substOptions);
2742+
2743+ // If any unresolved dependent member types remain, give up.
2744+ if (containsConcreteDependentMemberType (substTy))
2745+ return nullptr ;
2746+
2747+ return substTy;
27322748 }
27332749
27342750 auto *assocTy = dmt->getAssocType ();
@@ -2765,7 +2781,7 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
27652781 // out so that we don't break any subst() invariants.
27662782 if (tyWitness->hasTypeParameter () ||
27672783 tyWitness->hasDependentMember ()) {
2768- tyWitness = tyWitness.transform (substCurrentTypeWitnesses);
2784+ tyWitness = tyWitness.transformRec (substCurrentTypeWitnesses);
27692785 }
27702786
27712787 if (tyWitness) {
@@ -2798,15 +2814,20 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
27982814 return tyWitness;
27992815 };
28002816
2801- type = type.transform (substCurrentTypeWitnesses);
2817+ type = type.transformRec (substCurrentTypeWitnesses);
28022818
28032819 // If substitution failed, give up.
2804- if (!type || type->hasError ())
2820+ if (!type || type->hasError ()) {
2821+ LLVM_DEBUG (llvm::dbgs () << " -- Simplification failed\n " );
28052822 return assocType;
2823+ }
2824+
2825+ // If any unresolved dependent member types remain, give up.
2826+ assert (!containsConcreteDependentMemberType (type));
28062827
28072828 type = dc->mapTypeIntoContext (type);
28082829
2809- LLVM_DEBUG (llvm::dbgs () << " Substituted witness type is " << type << " \n " ;);
2830+ LLVM_DEBUG (llvm::dbgs () << " Simplified witness type is " << type << " \n " ;);
28102831 }
28112832
28122833 if (const auto failed =
@@ -4229,11 +4250,11 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
42294250 conformance, requirement);
42304251
42314252 if (better == conformance) {
4232- LLVM_DEBUG (llvm::dbgs () << " Conformance to " << conformance->getProtocol ()
4253+ LLVM_DEBUG (llvm::dbgs () << " Conformance to " << conformance->getProtocol ()-> getName ()
42334254 << " is best\n " ;);
42344255 } else {
4235- LLVM_DEBUG (llvm::dbgs () << " Conformance to " << better->getProtocol ()
4236- << " is better than " << conformance->getProtocol ()
4256+ LLVM_DEBUG (llvm::dbgs () << " Conformance to " << better->getProtocol ()-> getName ()
4257+ << " is better than " << conformance->getProtocol ()-> getName ()
42374258 << " \n " ;);
42384259 }
42394260 if (better != conformance &&
0 commit comments