@@ -2582,6 +2582,15 @@ bool AssociatedTypeInference::checkConstrainedExtension(ExtensionDecl *ext) {
2582
2582
llvm_unreachable (" unhandled result" );
2583
2583
}
2584
2584
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
+
2585
2594
AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses (
2586
2595
ArrayRef<AssociatedTypeDecl *> unresolvedAssocTypes, unsigned reqDepth) {
2587
2596
if (unresolvedAssocTypes.empty ()) {
@@ -2709,15 +2718,15 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
2709
2718
llvm::SmallPtrSet<AssociatedTypeDecl *, 4 > circularityCheck;
2710
2719
circularityCheck.insert (assocType);
2711
2720
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> {
2714
2723
auto *const dmt = ty->getAs <DependentMemberType>();
2715
2724
if (!dmt) {
2716
- return ty ;
2725
+ return llvm::None ;
2717
2726
}
2718
2727
2719
2728
const auto substBase =
2720
- dmt->getBase ().transform (substCurrentTypeWitnesses);
2729
+ dmt->getBase ().transformRec (substCurrentTypeWitnesses);
2721
2730
if (!substBase) {
2722
2731
return nullptr ;
2723
2732
}
@@ -2726,9 +2735,16 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
2726
2735
// need to look up a tentative type witness. Otherwise, just substitute
2727
2736
// the base.
2728
2737
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;
2732
2748
}
2733
2749
2734
2750
auto *assocTy = dmt->getAssocType ();
@@ -2765,7 +2781,7 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
2765
2781
// out so that we don't break any subst() invariants.
2766
2782
if (tyWitness->hasTypeParameter () ||
2767
2783
tyWitness->hasDependentMember ()) {
2768
- tyWitness = tyWitness.transform (substCurrentTypeWitnesses);
2784
+ tyWitness = tyWitness.transformRec (substCurrentTypeWitnesses);
2769
2785
}
2770
2786
2771
2787
if (tyWitness) {
@@ -2798,15 +2814,20 @@ AssociatedTypeDecl *AssociatedTypeInference::inferAbstractTypeWitnesses(
2798
2814
return tyWitness;
2799
2815
};
2800
2816
2801
- type = type.transform (substCurrentTypeWitnesses);
2817
+ type = type.transformRec (substCurrentTypeWitnesses);
2802
2818
2803
2819
// If substitution failed, give up.
2804
- if (!type || type->hasError ())
2820
+ if (!type || type->hasError ()) {
2821
+ LLVM_DEBUG (llvm::dbgs () << " -- Simplification failed\n " );
2805
2822
return assocType;
2823
+ }
2824
+
2825
+ // If any unresolved dependent member types remain, give up.
2826
+ assert (!containsConcreteDependentMemberType (type));
2806
2827
2807
2828
type = dc->mapTypeIntoContext (type);
2808
2829
2809
- LLVM_DEBUG (llvm::dbgs () << " Substituted witness type is " << type << " \n " ;);
2830
+ LLVM_DEBUG (llvm::dbgs () << " Simplified witness type is " << type << " \n " ;);
2810
2831
}
2811
2832
2812
2833
if (const auto failed =
@@ -4229,11 +4250,11 @@ TypeWitnessRequest::evaluate(Evaluator &eval,
4229
4250
conformance, requirement);
4230
4251
4231
4252
if (better == conformance) {
4232
- LLVM_DEBUG (llvm::dbgs () << " Conformance to " << conformance->getProtocol ()
4253
+ LLVM_DEBUG (llvm::dbgs () << " Conformance to " << conformance->getProtocol ()-> getName ()
4233
4254
<< " is best\n " ;);
4234
4255
} 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 ()
4237
4258
<< " \n " ;);
4238
4259
}
4239
4260
if (better != conformance &&
0 commit comments