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