Skip to content

Commit 4823bf2

Browse files
committed
[ConstraintSystem] Use fallback type constraint to default pack expansion
Binding of pack expansion types is delayed until solving but use of `Defaultable` was preventing it from being considered early because that constraint impacts binding set ranking, switching to `FallbackType` constraint give us better semantics where pack expansion type variables are going to be bound as soon as they have a contextual type. Resolves: rdar://110819621
1 parent c0d0908 commit 4823bf2

File tree

2 files changed

+43
-1
lines changed

2 files changed

+43
-1
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1031,7 +1031,7 @@ Type ConstraintSystem::openPackExpansionType(PackExpansionType *expansion,
10311031
// This constraint is important to make sure that pack expansion always
10321032
// has a binding and connect pack expansion var to any type variables
10331033
// that appear in pattern and shape types.
1034-
addUnsolvedConstraint(Constraint::create(*this, ConstraintKind::Defaultable,
1034+
addUnsolvedConstraint(Constraint::create(*this, ConstraintKind::FallbackType,
10351035
expansionVar, openedPackExpansion,
10361036
expansionLoc));
10371037

test/Constraints/pack-expansion-expressions.swift

Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -561,3 +561,45 @@ func configure<T, each Element>(
561561
repeat item[keyPath: (each configuration).0] = (each configuration).1
562562
return item
563563
}
564+
565+
// rdar://110819621 - generic parameter is bound before pack expansion type which result in inference failures
566+
func test_that_expansions_are_bound_early() {
567+
struct Data {
568+
let prop: Int?
569+
}
570+
571+
struct Value<each T> {
572+
init(_ body: (repeat each T) -> Bool) {}
573+
}
574+
575+
func compute<Root, Value>(
576+
root: Root,
577+
keyPath: KeyPath<Root, Value>,
578+
other: Value) -> Bool { true }
579+
580+
func test_keypath(v: Int) {
581+
let _: Value<Data> = Value({
582+
compute(
583+
root: $0,
584+
keyPath: \.prop,
585+
other: v
586+
)
587+
}) // Ok
588+
589+
let _: Value = Value<Data>({
590+
compute(
591+
root: $0,
592+
keyPath: \.prop,
593+
other: v
594+
)
595+
}) // Ok
596+
}
597+
598+
func equal<Value>(_: Value, _: Value) -> Bool {}
599+
600+
func test_equality(i: Int) {
601+
let _: Value<Data> = Value({
602+
equal($0.prop, i) // Ok
603+
})
604+
}
605+
}

0 commit comments

Comments
 (0)