Skip to content

Commit c87e0e1

Browse files
committed
[ConstraintSystem] Implement uninitialized pattern binding support
This like `let x: Int` or `let (x, y), ...` are now supported by the constraint solver.
1 parent d64c19e commit c87e0e1

File tree

3 files changed

+46
-10
lines changed

3 files changed

+46
-10
lines changed

lib/Sema/CSApply.cpp

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8795,7 +8795,10 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
87958795
patternBinding->setPattern(
87968796
index, resultTarget->getInitializationPattern(),
87978797
resultTarget->getDeclContext());
8798-
patternBinding->setInit(index, resultTarget->getAsExpr());
8798+
8799+
if (patternBinding->getInit(index)) {
8800+
patternBinding->setInit(index, resultTarget->getAsExpr());
8801+
}
87998802
}
88008803

88018804
return target;
@@ -8810,6 +8813,21 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
88108813
wrappedVar, backingType->mapTypeOutOfContext());
88118814

88128815
return target;
8816+
} else if (auto *pattern = target.getAsUninitializedVar()) {
8817+
auto contextualPattern = target.getContextualPattern();
8818+
auto patternType = target.getTypeOfUninitializedVar();
8819+
8820+
TypeResolutionOptions options = TypeResolverContext::PatternBindingDecl;
8821+
options |= TypeResolutionFlags::OverrideType;
8822+
8823+
if (auto coercedPattern = TypeChecker::coercePatternToType(
8824+
contextualPattern, patternType, options)) {
8825+
auto resultTarget = target;
8826+
resultTarget.setPattern(coercedPattern);
8827+
return resultTarget;
8828+
}
8829+
8830+
return None;
88138831
} else {
88148832
auto fn = *target.getAsFunction();
88158833
if (rewriteFunction(fn))

lib/Sema/CSGen.cpp

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -3935,14 +3935,13 @@ bool ConstraintSystem::generateConstraints(
39353935
return true;
39363936

39373937
auto init = patternBinding->getInit(index);
3938-
if (!init) {
3939-
llvm_unreachable("Unsupported pattern binding entry");
3940-
}
39413938

3942-
// Generate constraints for the initialization.
3943-
auto target = SolutionApplicationTarget::forInitialization(
3944-
init, dc, patternType, pattern,
3945-
/*bindPatternVarsOneWay=*/true);
3939+
auto target = init ? SolutionApplicationTarget::forInitialization(
3940+
init, dc, patternType, pattern,
3941+
/*bindPatternVarsOneWay=*/true)
3942+
: SolutionApplicationTarget::forUninitializedVar(
3943+
patternBinding, index, pattern, patternType);
3944+
39463945
if (generateConstraints(target, FreeTypeVariableBinding::Disallow)) {
39473946
hadError = true;
39483947
continue;
@@ -3963,9 +3962,20 @@ bool ConstraintSystem::generateConstraints(
39633962

39643963
return generateWrappedPropertyTypeConstraints(
39653964
*this, /*initializerType=*/Type(), wrappedVar, propertyType);
3966-
}
3965+
} else {
3966+
auto pattern = target.getAsUninitializedVar();
3967+
auto locator = getConstraintLocator(
3968+
pattern, LocatorPathElt::ContextualType(CTP_Initialization));
3969+
3970+
// Generate constraints to bind all of the internal declarations
3971+
// and verify the pattern.
3972+
Type patternType = generateConstraints(
3973+
pattern, locator, /*shouldBindPatternVarsOneWay*/ true,
3974+
target.getPatternBindingOfUninitializedVar(),
3975+
target.getIndexOfUninitializedVar());
39673976

3968-
llvm_unreachable("Unsupported un-initialized variable");
3977+
return !patternType;
3978+
}
39693979
}
39703980
}
39713981
}

lib/Sema/ConstraintSystem.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5438,6 +5438,12 @@ SolutionApplicationTarget::forPropertyWrapperInitializer(
54385438

54395439
ContextualPattern
54405440
SolutionApplicationTarget::getContextualPattern() const {
5441+
if (kind == Kind::uninitializedVar) {
5442+
assert(patternBinding);
5443+
return ContextualPattern::forPatternBindingDecl(patternBinding,
5444+
uninitializedVar.index);
5445+
}
5446+
54415447
assert(kind == Kind::expression);
54425448
assert(expression.contextualPurpose == CTP_Initialization ||
54435449
expression.contextualPurpose == CTP_ForEachStmt);
@@ -5553,6 +5559,8 @@ void ConstraintSystem::diagnoseFailureFor(SolutionApplicationTarget target) {
55535559
nominal->diagnose(diag::property_wrapper_declared_here,
55545560
nominal->getName());
55555561
}
5562+
} else if (auto *var = target.getAsUninitializedVar()) {
5563+
DE.diagnose(target.getLoc(), diag::failed_to_produce_diagnostic);
55565564
} else {
55575565
// Emit a poor fallback message.
55585566
DE.diagnose(target.getAsFunction()->getLoc(),

0 commit comments

Comments
 (0)