Skip to content

Commit d010097

Browse files
committed
[CSSimplify] Allow converting pack expansion types and tuples with pack expansions to Void for closure result
Resolves: rdar://108904190 (cherry picked from commit effa261) (cherry picked from commit dc4ee4b)
1 parent cc71656 commit d010097

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
@@ -7039,6 +7039,14 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
70397039
return formUnsolvedResult();
70407040
}
70417041

7042+
// Closure result is allowed to convert to Void in certain circumstances,
7043+
// let's forego tuple matching because it is guaranteed to fail and jump
7044+
// to `() -> T` to `() -> Void` rule.
7045+
if (locator.endsWith<LocatorPathElt::ClosureBody>()) {
7046+
if (containsPackExpansionType(tuple1) && tuple2->isVoid())
7047+
break;
7048+
}
7049+
70427050
// Add each tuple type to the locator before matching the element types.
70437051
// This is useful for diagnostics, because the error message can use the
70447052
// full tuple type for several element mismatches. Use the original types
@@ -7336,22 +7344,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
73367344
}
73377345
}
73387346

7339-
// Matching types where one side is a pack expansion and the other is not
7340-
// means a pack expansion was used where it isn't supported.
7341-
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
7342-
if (!shouldAttemptFixes())
7343-
return getTypeMatchFailure(locator);
7344-
7345-
if (type1->isPlaceholder() || type2->isPlaceholder())
7346-
return getTypeMatchSuccess();
7347-
7348-
auto *loc = getConstraintLocator(locator);
7349-
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
7350-
return getTypeMatchFailure(locator);
7351-
7352-
return getTypeMatchSuccess();
7353-
}
7354-
73557347
if (kind >= ConstraintKind::Conversion) {
73567348
// An lvalue of type T1 can be converted to a value of type T2 so long as
73577349
// T1 is convertible to T2 (by loading the value). Note that we cannot get
@@ -7774,6 +7766,22 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
77747766
}
77757767
}
77767768

7769+
// Matching types where one side is a pack expansion and the other is not
7770+
// means a pack expansion was used where it isn't supported.
7771+
if (type1->is<PackExpansionType>() != type2->is<PackExpansionType>()) {
7772+
if (!shouldAttemptFixes())
7773+
return getTypeMatchFailure(locator);
7774+
7775+
if (type1->isPlaceholder() || type2->isPlaceholder())
7776+
return getTypeMatchSuccess();
7777+
7778+
auto *loc = getConstraintLocator(locator);
7779+
if (recordFix(AllowInvalidPackExpansion::create(*this, loc)))
7780+
return getTypeMatchFailure(locator);
7781+
7782+
return getTypeMatchSuccess();
7783+
}
7784+
77777785
// Attempt fixes iff it's allowed, both types are concrete and
77787786
// we are not in the middle of attempting one already.
77797787
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
@@ -501,3 +501,11 @@ do {
501501
_ = (repeat overloaded(42, each v)) // Ok
502502
}
503503
}
504+
505+
// rdar://108904190 - top-level 'repeat' not allowed in single-expression closures
506+
func test_pack_expansion_to_void_conv_for_closure_result<each T>(x: repeat each T) {
507+
let _: () -> Void = { repeat print(each x) } // Ok
508+
let _: () -> Void = { (repeat print(each x)) } // Ok
509+
let _: (Int) -> Void = { repeat ($0, print(each x)) } // expected-warning {{'repeat (Int, ())' is unused}}
510+
let _: (Int, String) -> Void = { ($0, repeat ($1, print(each x))) } // expected-warning {{'(Int, repeat (String, ()))' is unused}}
511+
}

0 commit comments

Comments
 (0)