Skip to content

[CSSimplify] Allow conversions between tuples with pack expansions and Any #65861

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
May 15, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 5 additions & 1 deletion lib/Sema/CSSimplify.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -6831,9 +6831,13 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
// becuase expansion could be defaulted to an empty pack which means
// that under substitution that element would disappear and the type
// would be just `(Int)`.
//
// Notable exception here is `Any` which doesn't require wrapping and
// would be handled by existental promotion in cases where it's allowed.
if (isTupleWithUnresolvedPackExpansion(origType1) ||
isTupleWithUnresolvedPackExpansion(origType2)) {
if (desugar1->is<TupleType>() != desugar2->is<TupleType>()) {
if (desugar1->is<TupleType>() != desugar2->is<TupleType>() &&
(!desugar1->isAny() && !desugar2->isAny())) {
return matchTypes(
desugar1->is<TupleType>() ? type1
: TupleType::get({type1}, getASTContext()),
Expand Down
20 changes: 20 additions & 0 deletions test/Constraints/pack-expansion-expressions.swift
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,26 @@ func test_partually_flattened_expansions() {
_ = S<Int, String>().fn(t: 1, "hi", u: false, 1.0) // Ok
}

// rdar://109160060 - tuple with pack expansions is not convertible to Any
do {
func test1<each T>(_: repeat (each T).Type) -> (repeat each T) {}
print(test1(Int.self, String.self))

func test2<each T>(_ s: [Any], t: repeat (each T).Type) -> (repeat each T) {
var iter = s.makeIterator()
return (repeat (iter.next()! as! (each T)))
}

print(test2([]))
print(test2([1], t: Int.self))
print(test2([1, "hi"], t: Int.self, String.self))
print(test2([1, "hi", false], t: Int.self, String.self, Bool.self))

func test3<each T>(v: Any) -> (Int, repeat each T) {
return v // expected-error {{cannot convert return expression of type 'Any' to return type '(Int, repeat each T)'}}
}
}

// rdar://107675464 - misplaced `each` results in `type of expression is ambiguous without more context`
do {
func test_correct_each<each T: P>(_ value: repeat each T) -> (repeat each T.A) {
Expand Down