Skip to content

Commit f671c9d

Browse files
committed
[CSSimplify] Allow conversions between tuples with pack expansions and Any
Don't attempt to wrap `Any` into a single-element tuple to match against a tuple with pack expansions, this conversion would be handled by existential promotion if it's allowed, otherwise it would produce an error. Resolves: rdar://109160060 (cherry picked from commit 181d2d1)
1 parent a0884ed commit f671c9d

File tree

2 files changed

+25
-1
lines changed

2 files changed

+25
-1
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6885,9 +6885,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
68856885
// becuase expansion could be defaulted to an empty pack which means
68866886
// that under substitution that element would disappear and the type
68876887
// would be just `(Int)`.
6888+
//
6889+
// Notable exception here is `Any` which doesn't require wrapping and
6890+
// would be handled by existental promotion in cases where it's allowed.
68886891
if (isTupleWithUnresolvedPackExpansion(origType1) ||
68896892
isTupleWithUnresolvedPackExpansion(origType2)) {
6890-
if (desugar1->is<TupleType>() != desugar2->is<TupleType>()) {
6893+
if (desugar1->is<TupleType>() != desugar2->is<TupleType>() &&
6894+
(!desugar1->isAny() && !desugar2->isAny())) {
68916895
return matchTypes(
68926896
desugar1->is<TupleType>() ? type1
68936897
: TupleType::get({type1}, getASTContext()),

test/Constraints/pack-expansion-expressions.swift

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,26 @@ func test_partually_flattened_expansions() {
453453
_ = S<Int, String>().fn(t: 1, "hi", u: false, 1.0) // Ok
454454
}
455455

456+
// rdar://109160060 - tuple with pack expansions is not convertible to Any
457+
do {
458+
func test1<each T>(_: repeat (each T).Type) -> (repeat each T) {}
459+
print(test1(Int.self, String.self))
460+
461+
func test2<each T>(_ s: [Any], t: repeat (each T).Type) -> (repeat each T) {
462+
var iter = s.makeIterator()
463+
return (repeat (iter.next()! as! (each T)))
464+
}
465+
466+
print(test2([]))
467+
print(test2([1], t: Int.self))
468+
print(test2([1, "hi"], t: Int.self, String.self))
469+
print(test2([1, "hi", false], t: Int.self, String.self, Bool.self))
470+
471+
func test3<each T>(v: Any) -> (Int, repeat each T) {
472+
return v // expected-error {{cannot convert return expression of type 'Any' to return type '(Int, repeat each T)'}}
473+
}
474+
}
475+
456476
// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without more context`
457477
do {
458478
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {

0 commit comments

Comments
 (0)