Skip to content

Commit b897654

Browse files
authored
Merge pull request #59560 from xedin/issue-59522
[CSGen] Emulate separate type-checking of `$generator` variable of for-in loop
2 parents 7b00925 + 20a342b commit b897654

File tree

2 files changed

+18
-1
lines changed

2 files changed

+18
-1
lines changed

lib/Sema/CSGen.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3944,8 +3944,20 @@ generateForEachStmtConstraints(
39443944
forEachStmtInfo.makeIteratorVar = PB;
39453945

39463946
// Type of sequence expression has to conform to Sequence protocol.
3947+
//
3948+
// Note that the following emulates having `$generator` separately
3949+
// type-checked by introducing a `TVO_PrefersSubtypeBinding` type
3950+
// variable that would make sure that result of `.makeIterator` would
3951+
// get ranked standalone.
39473952
{
3948-
cs.addConstraint(ConstraintKind::ConformsTo, cs.getType(sequenceExpr),
3953+
auto *externalIteratorType = cs.createTypeVariable(
3954+
cs.getConstraintLocator(sequenceExpr), TVO_PrefersSubtypeBinding);
3955+
3956+
cs.addConstraint(ConstraintKind::Equal, externalIteratorType,
3957+
cs.getType(sequenceExpr),
3958+
externalIteratorType->getImpl().getLocator());
3959+
3960+
cs.addConstraint(ConstraintKind::ConformsTo, externalIteratorType,
39493961
sequenceProto->getDeclaredInterfaceType(),
39503962
contextualLocator);
39513963

test/stmt/foreach.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -245,3 +245,8 @@ func testForEachWhereWithClosure(_ x: [Int]) {
245245
for i in x where x.contains(where: { $0.byteSwapped == i }) {}
246246
}
247247

248+
// https://github.com/apple/swift/issues/59522 - use of `prefix` with generic base causes ambiguity in for-in statement
249+
func test_no_ambiguity_with_prefix_iterator<C: Collection>(c: C) {
250+
for _ in c.prefix(1) { // Ok
251+
}
252+
}

0 commit comments

Comments
 (0)