Skip to content

Commit fdf6d62

Browse files
authored
Merge pull request #65830 from xedin/rdar-108904190
[CSSimplify] Allow converting pack expansion types and tuples with pack expansions to Void for closure result
2 parents aa07794 + dc4ee4b commit fdf6d62

File tree

2 files changed

+32
-16
lines changed

2 files changed

+32
-16
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6989,6 +6989,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
69896989
return formUnsolvedResult();
69906990
}
69916991

6992+
// Closure result is allowed to convert to Void in certain circumstances,
6993+
// let's forego tuple matching because it is guaranteed to fail and jump
6994+
// to `() -> T` to `() -> Void` rule.
6995+
if (locator.endsWith<LocatorPathElt::ClosureBody>()) {
6996+
if (containsPackExpansionType(tuple1) && tuple2->isVoid())
6997+
break;
6998+
}
6999+
69927000
// Add each tuple type to the locator before matching the element types.
69937001
// This is useful for diagnostics, because the error message can use the
69947002
// full tuple type for several element mismatches. Use the original types
@@ -7286,22 +7294,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
72867294
}
72877295
}
72887296

7289-
// Matching types where one side is a pack expansion and the other is not
7290-
// means a pack expansion was used where it isn't supported.
7291-
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
7292-
if (!shouldAttemptFixes())
7293-
return getTypeMatchFailure(locator);
7294-
7295-
if (type1->isPlaceholder() || type2->isPlaceholder())
7296-
return getTypeMatchSuccess();
7297-
7298-
auto *loc = getConstraintLocator(locator);
7299-
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
7300-
return getTypeMatchFailure(locator);
7301-
7302-
return getTypeMatchSuccess();
7303-
}
7304-
73057297
if (kind >= ConstraintKind::Conversion) {
73067298
// An lvalue of type T1 can be converted to a value of type T2 so long as
73077299
// T1 is convertible to T2 (by loading the value). Note that we cannot get
@@ -7724,6 +7716,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
77247716
}
77257717
}
77267718

7719+
// Matching types where one side is a pack expansion and the other is not
7720+
// means a pack expansion was used where it isn't supported.
7721+
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
7722+
if (!shouldAttemptFixes())
7723+
return getTypeMatchFailure(locator);
7724+
7725+
if (type1->isPlaceholder() || type2->isPlaceholder())
7726+
return getTypeMatchSuccess();
7727+
7728+
auto *loc = getConstraintLocator(locator);
7729+
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
7730+
return getTypeMatchFailure(locator);
7731+
7732+
return getTypeMatchSuccess();
7733+
}
7734+
77277735
// Attempt fixes iff it's allowed, both types are concrete and
77287736
// we are not in the middle of attempting one already.
77297737
if (shouldAttemptFixes() && !flags.contains(TMF_ApplyingFix)) {

test/Constraints/pack-expansion-expressions.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -513,3 +513,11 @@ do {
513513
_ = (repeat overloaded(42, each v)) // Ok
514514
}
515515
}
516+
517+
// rdar://108904190 - top-level 'repeat' not allowed in single-expression closures
518+
func test_pack_expansion_to_void_conv_for_closure_result<each T>(x: repeat each T) {
519+
let _: () -> Void = { repeat print(each x) } // Ok
520+
let _: () -> Void = { (repeat print(each x)) } // Ok
521+
let _: (Int) -> Void = { repeat ($0, print(each x)) } // expected-warning {{'repeat (Int, ())' is unused}}
522+
let _: (Int, String) -> Void = { ($0, repeat ($1, print(each x))) } // expected-warning {{'(Int, repeat (String, ()))' is unused}}
523+
}

0 commit comments

Comments
 (0)