Skip to content

Commit 4ed65f8

Browse files
authored
Merge pull request #66709 from xedin/fix-late-binding-of-pack-expansions-5.9
[5.9][ConstraintSystem] Use fallback type constraint to default pack expansion
2 parents b3d1207 + fae9a2e commit 4ed65f8

File tree

9 files changed

+91
-51
lines changed

9 files changed

+91
-51
lines changed

include/swift/Sema/Constraint.h

+4-6
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,12 @@ enum class ConstraintKind : char {
186186
/// constraint.
187187
OneWayBindParam,
188188
/// If there is no contextual info e.g. `_ = { 42 }` default first type
189-
/// to a second type (inferred closure type). This is effectively a
190-
/// `Defaultable` constraint which a couple of differences:
189+
/// to a second type. This is effectively a `Defaultable` constraint
190+
/// which one significant difference:
191191
///
192-
/// - References inferred closure type and all of the outer parameters
193-
/// referenced by closure body.
194192
/// - Handled specially by binding inference, specifically contributes
195193
/// to the bindings only if there are no contextual types available.
196-
DefaultClosureType,
194+
FallbackType,
197195
/// The first type represents a result of an unresolved member chain,
198196
/// and the second type is its base type. This constraint acts almost
199197
/// like `Equal` but also enforces following semantics:
@@ -701,7 +699,7 @@ class Constraint final : public llvm::ilist_node<Constraint>,
701699
case ConstraintKind::OptionalObject:
702700
case ConstraintKind::OneWayEqual:
703701
case ConstraintKind::OneWayBindParam:
704-
case ConstraintKind::DefaultClosureType:
702+
case ConstraintKind::FallbackType:
705703
case ConstraintKind::UnresolvedMemberChainBase:
706704
case ConstraintKind::PackElementOf:
707705
case ConstraintKind::SameShape:

include/swift/Sema/ConstraintSystem.h

+6-5
Original file line numberDiff line numberDiff line change
@@ -4847,11 +4847,12 @@ class ConstraintSystem {
48474847
TypeMatchOptions flags,
48484848
ConstraintLocatorBuilder locator);
48494849

4850-
/// Attempt to simplify the given defaultable closure type constraint.
4851-
SolutionKind simplifyDefaultClosureTypeConstraint(
4852-
Type closureType, Type inferredType,
4853-
ArrayRef<TypeVariableType *> referencedOuterParameters,
4854-
TypeMatchOptions flags, ConstraintLocatorBuilder locator);
4850+
/// Attempt to simplify the given fallback type constraint.
4851+
SolutionKind
4852+
simplifyFallbackTypeConstraint(Type defaultableType, Type fallbackType,
4853+
ArrayRef<TypeVariableType *> referencedVars,
4854+
TypeMatchOptions flags,
4855+
ConstraintLocatorBuilder locator);
48554856

48564857
/// Attempt to simplify a property wrapper constraint.
48574858
SolutionKind simplifyPropertyWrapperConstraint(Type wrapperType, Type wrappedValueType,

lib/Sema/CSBindings.cpp

+7-8
Original file line numberDiff line numberDiff line change
@@ -452,7 +452,7 @@ void BindingSet::inferTransitiveBindings(
452452

453453
// Infer transitive defaults.
454454
for (const auto &def : bindings.Defaults) {
455-
if (def.getSecond()->getKind() == ConstraintKind::DefaultClosureType)
455+
if (def.getSecond()->getKind() == ConstraintKind::FallbackType)
456456
continue;
457457

458458
addDefault(def.second);
@@ -1510,7 +1510,7 @@ void PotentialBindings::infer(Constraint *constraint) {
15101510
}
15111511

15121512
case ConstraintKind::Defaultable:
1513-
case ConstraintKind::DefaultClosureType:
1513+
case ConstraintKind::FallbackType:
15141514
// Do these in a separate pass.
15151515
if (CS.getFixedTypeRecursive(constraint->getFirstType(), true)
15161516
->getAs<TypeVariableType>() == TypeVar) {
@@ -1634,7 +1634,7 @@ void PotentialBindings::retract(Constraint *constraint) {
16341634
break;
16351635

16361636
case ConstraintKind::Defaultable:
1637-
case ConstraintKind::DefaultClosureType: {
1637+
case ConstraintKind::FallbackType: {
16381638
Defaults.erase(constraint);
16391639
break;
16401640
}
@@ -2075,11 +2075,10 @@ bool TypeVarBindingProducer::computeNext() {
20752075
if (NumTries == 0) {
20762076
// Add defaultable constraints (if any).
20772077
for (auto *constraint : DelayedDefaults) {
2078-
if (constraint->getKind() == ConstraintKind::DefaultClosureType) {
2079-
// If there are no other possible bindings for this closure
2080-
// let's default it to the type inferred from its parameters/body,
2081-
// otherwise we should only attempt contextual types as a
2082-
// top-level closure type.
2078+
if (constraint->getKind() == ConstraintKind::FallbackType) {
2079+
// If there are no other possible bindings for this variable
2080+
// let's default it to the fallback type, otherwise we should
2081+
// only attempt contextual types.
20832082
if (!ExploredTypes.empty())
20842083
continue;
20852084
}

lib/Sema/CSGen.cpp

+3-3
Original file line numberDiff line numberDiff line change
@@ -2921,9 +2921,9 @@ namespace {
29212921
SmallVector<TypeVariableType *, 4> referencedVars{
29222922
collectVarRefs.varRefs.begin(), collectVarRefs.varRefs.end()};
29232923

2924-
CS.addUnsolvedConstraint(Constraint::create(
2925-
CS, ConstraintKind::DefaultClosureType, closureType, inferredType,
2926-
locator, referencedVars));
2924+
CS.addUnsolvedConstraint(
2925+
Constraint::create(CS, ConstraintKind::FallbackType, closureType,
2926+
inferredType, locator, referencedVars));
29272927

29282928
CS.setClosureType(closure, inferredType);
29292929
return closureType;

lib/Sema/CSSimplify.cpp

+20-20
Original file line numberDiff line numberDiff line change
@@ -2284,7 +2284,7 @@ ConstraintSystem::matchTupleTypes(TupleType *tuple1, TupleType *tuple2,
22842284
case ConstraintKind::BridgingConversion:
22852285
case ConstraintKind::OneWayEqual:
22862286
case ConstraintKind::OneWayBindParam:
2287-
case ConstraintKind::DefaultClosureType:
2287+
case ConstraintKind::FallbackType:
22882288
case ConstraintKind::UnresolvedMemberChainBase:
22892289
case ConstraintKind::PropertyWrapper:
22902290
case ConstraintKind::SyntacticElement:
@@ -2643,7 +2643,7 @@ static bool matchFunctionRepresentations(FunctionType::ExtInfo einfo1,
26432643
case ConstraintKind::ValueWitness:
26442644
case ConstraintKind::OneWayEqual:
26452645
case ConstraintKind::OneWayBindParam:
2646-
case ConstraintKind::DefaultClosureType:
2646+
case ConstraintKind::FallbackType:
26472647
case ConstraintKind::UnresolvedMemberChainBase:
26482648
case ConstraintKind::PropertyWrapper:
26492649
case ConstraintKind::SyntacticElement:
@@ -3161,7 +3161,7 @@ ConstraintSystem::matchFunctionTypes(FunctionType *func1, FunctionType *func2,
31613161
case ConstraintKind::BridgingConversion:
31623162
case ConstraintKind::OneWayEqual:
31633163
case ConstraintKind::OneWayBindParam:
3164-
case ConstraintKind::DefaultClosureType:
3164+
case ConstraintKind::FallbackType:
31653165
case ConstraintKind::UnresolvedMemberChainBase:
31663166
case ConstraintKind::PropertyWrapper:
31673167
case ConstraintKind::SyntacticElement:
@@ -6814,7 +6814,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
68146814
case ConstraintKind::ValueWitness:
68156815
case ConstraintKind::OneWayEqual:
68166816
case ConstraintKind::OneWayBindParam:
6817-
case ConstraintKind::DefaultClosureType:
6817+
case ConstraintKind::FallbackType:
68186818
case ConstraintKind::UnresolvedMemberChainBase:
68196819
case ConstraintKind::PropertyWrapper:
68206820
case ConstraintKind::SyntacticElement:
@@ -10950,18 +10950,18 @@ ConstraintSystem::SolutionKind ConstraintSystem::simplifyDefaultableConstraint(
1095010950
return SolutionKind::Solved;
1095110951
}
1095210952

10953-
ConstraintSystem::SolutionKind
10954-
ConstraintSystem::simplifyDefaultClosureTypeConstraint(
10955-
Type closureType, Type inferredType,
10956-
ArrayRef<TypeVariableType *> referencedOuterParameters,
10957-
TypeMatchOptions flags, ConstraintLocatorBuilder locator) {
10958-
closureType = getFixedTypeRecursive(closureType, flags, /*wantRValue=*/true);
10953+
ConstraintSystem::SolutionKind ConstraintSystem::simplifyFallbackTypeConstraint(
10954+
Type defaultableType, Type fallbackType,
10955+
ArrayRef<TypeVariableType *> referencedVars, TypeMatchOptions flags,
10956+
ConstraintLocatorBuilder locator) {
10957+
defaultableType =
10958+
getFixedTypeRecursive(defaultableType, flags, /*wantRValue=*/true);
1095910959

10960-
if (closureType->isTypeVariableOrMember()) {
10960+
if (defaultableType->isTypeVariableOrMember()) {
1096110961
if (flags.contains(TMF_GenerateConstraints)) {
1096210962
addUnsolvedConstraint(Constraint::create(
10963-
*this, ConstraintKind::DefaultClosureType, closureType, inferredType,
10964-
getConstraintLocator(locator), referencedOuterParameters));
10963+
*this, ConstraintKind::FallbackType, defaultableType, fallbackType,
10964+
getConstraintLocator(locator), referencedVars));
1096510965
return SolutionKind::Solved;
1096610966
}
1096710967

@@ -15014,7 +15014,7 @@ ConstraintSystem::addConstraintImpl(ConstraintKind kind, Type first,
1501415014
case ConstraintKind::Conjunction:
1501515015
case ConstraintKind::KeyPath:
1501615016
case ConstraintKind::KeyPathApplication:
15017-
case ConstraintKind::DefaultClosureType:
15017+
case ConstraintKind::FallbackType:
1501815018
case ConstraintKind::SyntacticElement:
1501915019
llvm_unreachable("Use the correct addConstraint()");
1502015020
}
@@ -15546,12 +15546,12 @@ ConstraintSystem::simplifyConstraint(const Constraint &constraint) {
1554615546
/*flags*/ None,
1554715547
constraint.getLocator());
1554815548

15549-
case ConstraintKind::DefaultClosureType:
15550-
return simplifyDefaultClosureTypeConstraint(constraint.getFirstType(),
15551-
constraint.getSecondType(),
15552-
constraint.getTypeVariables(),
15553-
/*flags*/ None,
15554-
constraint.getLocator());
15549+
case ConstraintKind::FallbackType:
15550+
return simplifyFallbackTypeConstraint(constraint.getFirstType(),
15551+
constraint.getSecondType(),
15552+
constraint.getTypeVariables(),
15553+
/*flags*/ None,
15554+
constraint.getLocator());
1555515555

1555615556
case ConstraintKind::PropertyWrapper:
1555715557
return simplifyPropertyWrapperConstraint(constraint.getFirstType(),

lib/Sema/Constraint.cpp

+6-6
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second,
9999
llvm_unreachable("Wrong constructor for member constraint");
100100

101101
case ConstraintKind::Defaultable:
102-
case ConstraintKind::DefaultClosureType:
102+
case ConstraintKind::FallbackType:
103103
assert(!First.isNull());
104104
assert(!Second.isNull());
105105
break;
@@ -164,7 +164,7 @@ Constraint::Constraint(ConstraintKind Kind, Type First, Type Second, Type Third,
164164
case ConstraintKind::Conjunction:
165165
case ConstraintKind::OneWayEqual:
166166
case ConstraintKind::OneWayBindParam:
167-
case ConstraintKind::DefaultClosureType:
167+
case ConstraintKind::FallbackType:
168168
case ConstraintKind::UnresolvedMemberChainBase:
169169
case ConstraintKind::PropertyWrapper:
170170
case ConstraintKind::SyntacticElement:
@@ -314,7 +314,7 @@ Constraint *Constraint::clone(ConstraintSystem &cs) const {
314314
case ConstraintKind::Defaultable:
315315
case ConstraintKind::OneWayEqual:
316316
case ConstraintKind::OneWayBindParam:
317-
case ConstraintKind::DefaultClosureType:
317+
case ConstraintKind::FallbackType:
318318
case ConstraintKind::UnresolvedMemberChainBase:
319319
case ConstraintKind::PropertyWrapper:
320320
case ConstraintKind::BindTupleOfFunctionParams:
@@ -470,8 +470,8 @@ void Constraint::print(llvm::raw_ostream &Out, SourceManager *sm,
470470
case ConstraintKind::OpenedExistentialOf: Out << " opened archetype of "; break;
471471
case ConstraintKind::OneWayEqual: Out << " one-way bind to "; break;
472472
case ConstraintKind::OneWayBindParam: Out << " one-way bind param to "; break;
473-
case ConstraintKind::DefaultClosureType:
474-
Out << " closure can default to ";
473+
case ConstraintKind::FallbackType:
474+
Out << " can fallback to ";
475475
break;
476476
case ConstraintKind::UnresolvedMemberChainBase:
477477
Out << " unresolved member chain base ";
@@ -742,7 +742,7 @@ gatherReferencedTypeVars(Constraint *constraint,
742742
case ConstraintKind::SelfObjectOfProtocol:
743743
case ConstraintKind::OneWayEqual:
744744
case ConstraintKind::OneWayBindParam:
745-
case ConstraintKind::DefaultClosureType:
745+
case ConstraintKind::FallbackType:
746746
case ConstraintKind::UnresolvedMemberChainBase:
747747
case ConstraintKind::PropertyWrapper:
748748
case ConstraintKind::BindTupleOfFunctionParams:

lib/Sema/ConstraintSystem.cpp

+2-2
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

@@ -7391,7 +7391,7 @@ bool TypeVarBindingProducer::requiresOptionalAdjustment(
73917391
PotentialBinding
73927392
TypeVarBindingProducer::getDefaultBinding(Constraint *constraint) const {
73937393
assert(constraint->getKind() == ConstraintKind::Defaultable ||
7394-
constraint->getKind() == ConstraintKind::DefaultClosureType);
7394+
constraint->getKind() == ConstraintKind::FallbackType);
73957395

73967396
auto type = constraint->getSecondType();
73977397
Binding binding{type, BindingKind::Exact, constraint};

test/Constraints/pack-expansion-expressions.swift

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

unittests/Sema/ConstraintSimplificationTests.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ TEST_F(SemaTest, TestClosureInferenceFromOptionalContext) {
111111
auto *closureTy = cs.createTypeVariable(closureLoc, /*options=*/0);
112112

113113
cs.addUnsolvedConstraint(Constraint::create(
114-
cs, ConstraintKind::DefaultClosureType, closureTy, defaultTy,
114+
cs, ConstraintKind::FallbackType, closureTy, defaultTy,
115115
cs.getConstraintLocator(closure), /*referencedVars=*/{}));
116116

117117
auto contextualTy =

0 commit comments

Comments
 (0)