@@ -9286,45 +9286,41 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyMemberConstraint(
9286
9286
};
9287
9287
9288
9288
auto *baseExpr = memberRef->getBase();
9289
- // If base type is an existential, member lookup is fine because
9290
- // it would return a witness.
9291
- if (!baseObjTy->isExistentialType()) {
9292
- // Handle `makeIterator` reference.
9293
- if (getContextualTypePurpose(baseExpr) == CTP_ForEachSequence &&
9294
- isRefTo(memberRef, ctx.Id_makeIterator, /*lables=*/{})) {
9295
- auto *sequenceProto = cast<ProtocolDecl>(
9296
- getContextualType(baseExpr, /*forConstraint=*/false)
9297
- ->getAnyNominal());
9298
- bool isAsync = sequenceProto == TypeChecker::getProtocol(
9299
- ctx, SourceLoc(),
9300
- KnownProtocolKind::AsyncSequence);
9301
-
9302
- auto *makeIterator = isAsync ? ctx.getAsyncSequenceMakeAsyncIterator()
9303
- : ctx.getSequenceMakeIterator();
9304
-
9305
- return simplifyValueWitnessConstraint(
9306
- ConstraintKind::ValueWitness, baseTy, makeIterator, memberTy, DC,
9307
- FunctionRefKind::Compound, flags, locator);
9308
- }
9289
+ // Handle `makeIterator` reference.
9290
+ if (getContextualTypePurpose(baseExpr) == CTP_ForEachSequence &&
9291
+ isRefTo(memberRef, ctx.Id_makeIterator, /*lables=*/{})) {
9292
+ auto *sequenceProto = cast<ProtocolDecl>(
9293
+ getContextualType(baseExpr, /*forConstraint=*/false)
9294
+ ->getAnyNominal());
9295
+ bool isAsync = sequenceProto ==
9296
+ TypeChecker::getProtocol(
9297
+ ctx, SourceLoc(), KnownProtocolKind::AsyncSequence);
9309
9298
9310
- // Handle `next` reference.
9311
- if (getContextualTypePurpose(baseExpr) == CTP_ForEachSequence &&
9312
- isRefTo(memberRef, ctx.Id_next, /*labels=*/{})) {
9313
- auto *iteratorProto = cast<ProtocolDecl>(
9314
- getContextualType(baseExpr, /*forConstraint=*/false)
9315
- ->getAnyNominal());
9316
- bool isAsync =
9317
- iteratorProto ==
9318
- TypeChecker::getProtocol(
9319
- ctx, SourceLoc(), KnownProtocolKind::AsyncIteratorProtocol);
9320
-
9321
- auto *next =
9322
- isAsync ? ctx.getAsyncIteratorNext() : ctx.getIteratorNext();
9323
-
9324
- return simplifyValueWitnessConstraint(
9325
- ConstraintKind::ValueWitness, baseTy, next, memberTy, DC,
9326
- FunctionRefKind::Compound, flags, locator);
9327
- }
9299
+ auto *makeIterator = isAsync ? ctx.getAsyncSequenceMakeAsyncIterator()
9300
+ : ctx.getSequenceMakeIterator();
9301
+
9302
+ return simplifyValueWitnessConstraint(
9303
+ ConstraintKind::ValueWitness, baseTy, makeIterator, memberTy, useDC,
9304
+ FunctionRefKind::Compound, flags, locator);
9305
+ }
9306
+
9307
+ // Handle `next` reference.
9308
+ if (getContextualTypePurpose(baseExpr) == CTP_ForEachSequence &&
9309
+ isRefTo(memberRef, ctx.Id_next, /*labels=*/{})) {
9310
+ auto *iteratorProto = cast<ProtocolDecl>(
9311
+ getContextualType(baseExpr, /*forConstraint=*/false)
9312
+ ->getAnyNominal());
9313
+ bool isAsync =
9314
+ iteratorProto ==
9315
+ TypeChecker::getProtocol(ctx, SourceLoc(),
9316
+ KnownProtocolKind::AsyncIteratorProtocol);
9317
+
9318
+ auto *next =
9319
+ isAsync ? ctx.getAsyncIteratorNext() : ctx.getIteratorNext();
9320
+
9321
+ return simplifyValueWitnessConstraint(
9322
+ ConstraintKind::ValueWitness, baseTy, next, memberTy, useDC,
9323
+ FunctionRefKind::Compound, flags, locator);
9328
9324
}
9329
9325
}
9330
9326
}
@@ -9784,6 +9780,14 @@ ConstraintSystem::simplifyValueWitnessConstraint(
9784
9780
return formUnsolved();
9785
9781
}
9786
9782
9783
+ // If base type is an existential, let's open it before checking
9784
+ // conformance.
9785
+ if (baseObjectType->isExistentialType()) {
9786
+ baseObjectType =
9787
+ OpenedArchetypeType::get(baseObjectType->getCanonicalType(),
9788
+ useDC->getGenericSignatureOfContext());
9789
+ }
9790
+
9787
9791
// Check conformance to the protocol. If it doesn't conform, this constraint
9788
9792
// fails. Don't attempt to fix it.
9789
9793
// FIXME: Look in the constraint system to see if we've resolved the
0 commit comments