Skip to content

Commit a499bfc

Browse files
committed
Sema: Use new form of getOpenedExistentialSignature() in doesMemberHaveUnfulfillableConstraintsWithExistentialBase()
1 parent c0f1fd4 commit a499bfc

File tree

1 file changed

+38
-12
lines changed

1 file changed

+38
-12
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 38 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)