@@ -7447,14 +7447,21 @@ static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase(
74477447 return false ;
74487448 }
74497449
7450- class IsDependentOnSelfInBaseTypeContextWalker : public TypeWalker {
7451- CanGenericSignature Sig;
7450+ auto &ctx = member->getASTContext ();
7451+ auto existentialSig = ctx.getOpenedExistentialSignature (baseTy);
7452+
7453+ class IsDependentOnOpenedExistentialSelf : public TypeWalker {
7454+ OpenedExistentialSignature existentialSig;
74527455
74537456 public:
7454- explicit IsDependentOnSelfInBaseTypeContextWalker (CanGenericSignature Sig )
7455- : Sig(Sig ) {}
7457+ explicit IsDependentOnOpenedExistentialSelf (OpenedExistentialSignature existentialSig )
7458+ : existentialSig(existentialSig ) {}
74567459
74577460 Action walkToTypePre (Type ty) override {
7461+ // We're looking at the interface type of a protocol member, so it's written
7462+ // in terms of `Self` (tau_0_0) and possibly type parameters at higher depth:
7463+ //
7464+ // <Self, ... where Self: P, ...>
74587465 if (!ty->isTypeParameter ()) {
74597466 return Action::Continue;
74607467 }
@@ -7463,25 +7470,44 @@ static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase(
74637470 return Action::SkipNode;
74647471 }
74657472
7466- if (!Sig->isValidTypeParameter (ty)) {
7473+ // Ok, we found a type parameter rooted in `Self`. Replace `Self` with the
7474+ // opened Self type in the existential signature, which looks like this:
7475+ //
7476+ // <..., Self where ..., Self: P>
7477+ ty = ty.subst (
7478+ [&](SubstitutableType *type) -> Type {
7479+ return existentialSig.SelfType ;
7480+ },
7481+ MakeAbstractConformanceForGenericType ());
7482+
7483+ // Make sure this is valid first.
7484+ if (!existentialSig.OpenedSig ->isValidTypeParameter (ty)) {
74677485 return Action::SkipNode;
74687486 }
74697487
7470- const auto concreteTy = Sig->getConcreteType (ty);
7471- if (concreteTy && !concreteTy->hasTypeParameter ()) {
7488+ // If the existential type constrains Self.U to a type from the outer
7489+ // context, then the reduced type of Self.U in the existential signature
7490+ // will no longer contain Self.
7491+ ty = existentialSig.OpenedSig .getReducedType (ty);
7492+
7493+ if (!ty.findIf ([&](Type t) -> bool {
7494+ if (auto *paramTy = t->getAs <GenericTypeParamType>())
7495+ return paramTy->isEqual (existentialSig.SelfType );
7496+ return false ;
7497+ })) {
74727498 return Action::SkipNode;
74737499 }
74747500
7501+ // Ok, we found a type that depends on the opened existential Self.
74757502 return Action::Stop;
74767503 }
7477- } isDependentOnSelfWalker (member->getASTContext ().getOpenedExistentialSignature (
7478- baseTy, GenericSignature ()));
7504+ } isDependentOnSelf (existentialSig);
74797505
74807506 for (const auto &req : sig.getRequirements ()) {
74817507 switch (req.getKind ()) {
74827508 case RequirementKind::Superclass: {
74837509 if (req.getFirstType ()->getRootGenericParam ()->getDepth () > 0 &&
7484- req.getSecondType ().walk (isDependentOnSelfWalker )) {
7510+ req.getSecondType ().walk (isDependentOnSelf )) {
74857511 return true ;
74867512 }
74877513
@@ -7495,9 +7521,9 @@ static bool doesMemberHaveUnfulfillableConstraintsWithExistentialBase(
74957521 };
74967522
74977523 if ((isNonSelfRootedTypeParam (req.getFirstType ()) &&
7498- req.getSecondType ().walk (isDependentOnSelfWalker )) ||
7524+ req.getSecondType ().walk (isDependentOnSelf )) ||
74997525 (isNonSelfRootedTypeParam (req.getSecondType ()) &&
7500- req.getFirstType ().walk (isDependentOnSelfWalker ))) {
7526+ req.getFirstType ().walk (isDependentOnSelf ))) {
75017527 return true ;
75027528 }
75037529
0 commit comments