Skip to content

Commit 9518286

Browse files
authored
Merge pull request #38912 from xedin/generalize-unitialized-var-target
[ConstraintSystem] Generalize uninitialized wrapped variable targets
2 parents 2460639 + 6ee42ab commit 9518286

File tree

5 files changed

+199
-42
lines changed

5 files changed

+199
-42
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 139 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1559,7 +1559,7 @@ class SolutionApplicationTarget {
15591559
stmtCondition,
15601560
caseLabelItem,
15611561
patternBinding,
1562-
uninitializedWrappedVar,
1562+
uninitializedVar,
15631563
} kind;
15641564

15651565
private:
@@ -1631,9 +1631,15 @@ class SolutionApplicationTarget {
16311631
DeclContext *dc;
16321632
} caseLabelItem;
16331633

1634-
PatternBindingDecl *patternBinding;
1634+
struct {
1635+
/// Index into pattern binding declaration (if any).
1636+
unsigned index;
1637+
PointerUnion<VarDecl *, Pattern *> declaration;
1638+
/// Type associated with the declaration.
1639+
Type type;
1640+
} uninitializedVar;
16351641

1636-
VarDecl *uninitializedWrappedVar;
1642+
PatternBindingDecl *patternBinding;
16371643
};
16381644

16391645
// If the pattern contains a single variable that has an attached
@@ -1679,9 +1685,29 @@ class SolutionApplicationTarget {
16791685
this->patternBinding = patternBinding;
16801686
}
16811687

1682-
SolutionApplicationTarget(VarDecl *wrappedVar) {
1683-
kind = Kind::uninitializedWrappedVar;
1684-
this->uninitializedWrappedVar= wrappedVar;
1688+
SolutionApplicationTarget(VarDecl *uninitializedWrappedVar)
1689+
: kind(Kind::uninitializedVar) {
1690+
if (auto *PDB = uninitializedWrappedVar->getParentPatternBinding()) {
1691+
patternBinding = PDB;
1692+
uninitializedVar.index =
1693+
PDB->getPatternEntryIndexForVarDecl(uninitializedWrappedVar);
1694+
} else {
1695+
uninitializedVar.index = 0;
1696+
}
1697+
1698+
uninitializedVar.declaration = uninitializedWrappedVar;
1699+
uninitializedVar.type = Type();
1700+
}
1701+
1702+
SolutionApplicationTarget(PatternBindingDecl *binding, unsigned index,
1703+
Pattern *var, Type patternTy)
1704+
: kind(Kind::uninitializedVar) {
1705+
assert(patternBinding);
1706+
1707+
patternBinding = binding;
1708+
uninitializedVar.index = index;
1709+
uninitializedVar.declaration = var;
1710+
uninitializedVar.type = patternTy;
16851711
}
16861712

16871713
/// Form a target for the initialization of a pattern from an expression.
@@ -1703,8 +1729,16 @@ class SolutionApplicationTarget {
17031729

17041730
/// Form a target for a property with an attached property wrapper that is
17051731
/// initialized out-of-line.
1706-
static SolutionApplicationTarget forUninitializedWrappedVar(
1707-
VarDecl *wrappedVar);
1732+
static SolutionApplicationTarget
1733+
forUninitializedWrappedVar(VarDecl *wrappedVar) {
1734+
return {wrappedVar};
1735+
}
1736+
1737+
static SolutionApplicationTarget
1738+
forUninitializedVar(PatternBindingDecl *binding, unsigned index, Pattern *var,
1739+
Type patternTy) {
1740+
return {binding, index, var, patternTy};
1741+
}
17081742

17091743
/// Form a target for a synthesized property wrapper initializer.
17101744
static SolutionApplicationTarget forPropertyWrapperInitializer(
@@ -1719,7 +1753,7 @@ class SolutionApplicationTarget {
17191753
case Kind::stmtCondition:
17201754
case Kind::caseLabelItem:
17211755
case Kind::patternBinding:
1722-
case Kind::uninitializedWrappedVar:
1756+
case Kind::uninitializedVar:
17231757
return nullptr;
17241758
}
17251759
llvm_unreachable("invalid expression type");
@@ -1742,8 +1776,13 @@ class SolutionApplicationTarget {
17421776
case Kind::patternBinding:
17431777
return patternBinding->getDeclContext();
17441778

1745-
case Kind::uninitializedWrappedVar:
1746-
return uninitializedWrappedVar->getDeclContext();
1779+
case Kind::uninitializedVar: {
1780+
if (auto *wrappedVar =
1781+
uninitializedVar.declaration.dyn_cast<VarDecl *>())
1782+
return wrappedVar->getDeclContext();
1783+
1784+
return patternBinding->getInitContext(uninitializedVar.index);
1785+
}
17471786
}
17481787
llvm_unreachable("invalid decl context type");
17491788
}
@@ -1799,6 +1838,9 @@ class SolutionApplicationTarget {
17991838

18001839
/// For a pattern initialization target, retrieve the pattern.
18011840
Pattern *getInitializationPattern() const {
1841+
if (kind == Kind::uninitializedVar)
1842+
return uninitializedVar.declaration.get<Pattern *>();
1843+
18021844
assert(kind == Kind::expression);
18031845
assert(expression.contextualPurpose == CTP_Initialization);
18041846
return expression.pattern;
@@ -1903,6 +1945,12 @@ class SolutionApplicationTarget {
19031945
}
19041946

19051947
void setPattern(Pattern *pattern) {
1948+
if (kind == Kind::uninitializedVar) {
1949+
assert(uninitializedVar.declaration.is<Pattern *>());
1950+
uninitializedVar.declaration = pattern;
1951+
return;
1952+
}
1953+
19061954
assert(kind == Kind::expression);
19071955
assert(expression.contextualPurpose == CTP_Initialization ||
19081956
expression.contextualPurpose == CTP_ForEachStmt);
@@ -1915,7 +1963,7 @@ class SolutionApplicationTarget {
19151963
case Kind::stmtCondition:
19161964
case Kind::caseLabelItem:
19171965
case Kind::patternBinding:
1918-
case Kind::uninitializedWrappedVar:
1966+
case Kind::uninitializedVar:
19191967
return None;
19201968

19211969
case Kind::function:
@@ -1930,7 +1978,7 @@ class SolutionApplicationTarget {
19301978
case Kind::function:
19311979
case Kind::caseLabelItem:
19321980
case Kind::patternBinding:
1933-
case Kind::uninitializedWrappedVar:
1981+
case Kind::uninitializedVar:
19341982
return None;
19351983

19361984
case Kind::stmtCondition:
@@ -1945,7 +1993,7 @@ class SolutionApplicationTarget {
19451993
case Kind::function:
19461994
case Kind::stmtCondition:
19471995
case Kind::patternBinding:
1948-
case Kind::uninitializedWrappedVar:
1996+
case Kind::uninitializedVar:
19491997
return None;
19501998

19511999
case Kind::caseLabelItem:
@@ -1960,7 +2008,7 @@ class SolutionApplicationTarget {
19602008
case Kind::function:
19612009
case Kind::stmtCondition:
19622010
case Kind::caseLabelItem:
1963-
case Kind::uninitializedWrappedVar:
2011+
case Kind::uninitializedVar:
19642012
return nullptr;
19652013

19662014
case Kind::patternBinding:
@@ -1978,8 +2026,68 @@ class SolutionApplicationTarget {
19782026
case Kind::patternBinding:
19792027
return nullptr;
19802028

1981-
case Kind::uninitializedWrappedVar:
1982-
return uninitializedWrappedVar;
2029+
case Kind::uninitializedVar:
2030+
return uninitializedVar.declaration.dyn_cast<VarDecl *>();
2031+
}
2032+
llvm_unreachable("invalid case label type");
2033+
}
2034+
2035+
Pattern *getAsUninitializedVar() const {
2036+
switch (kind) {
2037+
case Kind::expression:
2038+
case Kind::function:
2039+
case Kind::stmtCondition:
2040+
case Kind::caseLabelItem:
2041+
case Kind::patternBinding:
2042+
return nullptr;
2043+
2044+
case Kind::uninitializedVar:
2045+
return uninitializedVar.declaration.dyn_cast<Pattern *>();
2046+
}
2047+
llvm_unreachable("invalid case label type");
2048+
}
2049+
2050+
Type getTypeOfUninitializedVar() const {
2051+
switch (kind) {
2052+
case Kind::expression:
2053+
case Kind::function:
2054+
case Kind::stmtCondition:
2055+
case Kind::caseLabelItem:
2056+
case Kind::patternBinding:
2057+
return nullptr;
2058+
2059+
case Kind::uninitializedVar:
2060+
return uninitializedVar.type;
2061+
}
2062+
llvm_unreachable("invalid case label type");
2063+
}
2064+
2065+
PatternBindingDecl *getPatternBindingOfUninitializedVar() const {
2066+
switch (kind) {
2067+
case Kind::expression:
2068+
case Kind::function:
2069+
case Kind::stmtCondition:
2070+
case Kind::caseLabelItem:
2071+
case Kind::patternBinding:
2072+
return nullptr;
2073+
2074+
case Kind::uninitializedVar:
2075+
return patternBinding;
2076+
}
2077+
llvm_unreachable("invalid case label type");
2078+
}
2079+
2080+
unsigned getIndexOfUninitializedVar() const {
2081+
switch (kind) {
2082+
case Kind::expression:
2083+
case Kind::function:
2084+
case Kind::stmtCondition:
2085+
case Kind::caseLabelItem:
2086+
case Kind::patternBinding:
2087+
return 0;
2088+
2089+
case Kind::uninitializedVar:
2090+
return uninitializedVar.index;
19832091
}
19842092
llvm_unreachable("invalid case label type");
19852093
}
@@ -2013,8 +2121,13 @@ class SolutionApplicationTarget {
20132121
case Kind::patternBinding:
20142122
return patternBinding->getSourceRange();
20152123

2016-
case Kind::uninitializedWrappedVar:
2017-
return uninitializedWrappedVar->getSourceRange();
2124+
case Kind::uninitializedVar: {
2125+
if (auto *wrappedVar =
2126+
uninitializedVar.declaration.dyn_cast<VarDecl *>()) {
2127+
return wrappedVar->getSourceRange();
2128+
}
2129+
return uninitializedVar.declaration.get<Pattern *>()->getSourceRange();
2130+
}
20182131
}
20192132
llvm_unreachable("invalid target type");
20202133
}
@@ -2037,8 +2150,13 @@ class SolutionApplicationTarget {
20372150
case Kind::patternBinding:
20382151
return patternBinding->getLoc();
20392152

2040-
case Kind::uninitializedWrappedVar:
2041-
return uninitializedWrappedVar->getLoc();
2153+
case Kind::uninitializedVar: {
2154+
if (auto *wrappedVar =
2155+
uninitializedVar.declaration.dyn_cast<VarDecl *>()) {
2156+
return wrappedVar->getLoc();
2157+
}
2158+
return uninitializedVar.declaration.get<Pattern *>()->getLoc();
2159+
}
20422160
}
20432161
llvm_unreachable("invalid target type");
20442162
}

lib/Sema/CSApply.cpp

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8808,7 +8808,10 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
88088808
patternBinding->setPattern(
88098809
index, resultTarget->getInitializationPattern(),
88108810
resultTarget->getDeclContext());
8811-
patternBinding->setInit(index, resultTarget->getAsExpr());
8811+
8812+
if (patternBinding->getInit(index)) {
8813+
patternBinding->setInit(index, resultTarget->getAsExpr());
8814+
}
88128815
}
88138816

88148817
return target;
@@ -8823,6 +8826,21 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
88238826
wrappedVar, backingType->mapTypeOutOfContext());
88248827

88258828
return target;
8829+
} else if (auto *pattern = target.getAsUninitializedVar()) {
8830+
auto contextualPattern = target.getContextualPattern();
8831+
auto patternType = target.getTypeOfUninitializedVar();
8832+
8833+
TypeResolutionOptions options = TypeResolverContext::PatternBindingDecl;
8834+
options |= TypeResolutionFlags::OverrideType;
8835+
8836+
if (auto coercedPattern = TypeChecker::coercePatternToType(
8837+
contextualPattern, patternType, options)) {
8838+
auto resultTarget = target;
8839+
resultTarget.setPattern(coercedPattern);
8840+
return resultTarget;
8841+
}
8842+
8843+
return None;
88268844
} else {
88278845
auto fn = *target.getAsFunction();
88288846
if (rewriteFunction(fn))
@@ -9099,7 +9117,7 @@ SolutionApplicationTarget SolutionApplicationTarget::walk(ASTWalker &walker) {
90999117
case Kind::patternBinding:
91009118
return *this;
91019119

9102-
case Kind::uninitializedWrappedVar:
9120+
case Kind::uninitializedVar:
91039121
return *this;
91049122
}
91059123

lib/Sema/CSGen.cpp

Lines changed: 31 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3936,15 +3936,19 @@ bool ConstraintSystem::generateConstraints(
39363936
if (!patternType || patternType->hasError())
39373937
return true;
39383938

3939-
auto init = patternBinding->getInit(index);
3940-
if (!init) {
3941-
llvm_unreachable("Unsupported pattern binding entry");
3939+
if (!patternBinding->isInitialized(index) &&
3940+
patternBinding->isDefaultInitializable(index) &&
3941+
pattern->hasStorage()) {
3942+
llvm_unreachable("default initialization is unsupported");
39423943
}
39433944

3944-
// Generate constraints for the initialization.
3945-
auto target = SolutionApplicationTarget::forInitialization(
3946-
init, dc, patternType, pattern,
3947-
/*bindPatternVarsOneWay=*/true);
3945+
auto init = patternBinding->getInit(index);
3946+
auto target = init ? SolutionApplicationTarget::forInitialization(
3947+
init, dc, patternType, pattern,
3948+
/*bindPatternVarsOneWay=*/true)
3949+
: SolutionApplicationTarget::forUninitializedVar(
3950+
patternBinding, index, pattern, patternType);
3951+
39483952
if (generateConstraints(target, FreeTypeVariableBinding::Disallow)) {
39493953
hadError = true;
39503954
continue;
@@ -3957,14 +3961,28 @@ bool ConstraintSystem::generateConstraints(
39573961
return hadError;
39583962
}
39593963

3960-
case SolutionApplicationTarget::Kind::uninitializedWrappedVar: {
3961-
auto *wrappedVar = target.getAsUninitializedWrappedVar();
3962-
auto propertyType = getVarType(wrappedVar);
3963-
if (propertyType->hasError())
3964-
return true;
3964+
case SolutionApplicationTarget::Kind::uninitializedVar: {
3965+
if (auto *wrappedVar = target.getAsUninitializedWrappedVar()) {
3966+
auto propertyType = getVarType(wrappedVar);
3967+
if (propertyType->hasError())
3968+
return true;
39653969

3966-
return generateWrappedPropertyTypeConstraints(
3970+
return generateWrappedPropertyTypeConstraints(
39673971
*this, /*initializerType=*/Type(), wrappedVar, propertyType);
3972+
} else {
3973+
auto pattern = target.getAsUninitializedVar();
3974+
auto locator = getConstraintLocator(
3975+
pattern, LocatorPathElt::ContextualType(CTP_Initialization));
3976+
3977+
// Generate constraints to bind all of the internal declarations
3978+
// and verify the pattern.
3979+
Type patternType = generateConstraints(
3980+
pattern, locator, /*shouldBindPatternVarsOneWay*/ true,
3981+
target.getPatternBindingOfUninitializedVar(),
3982+
target.getIndexOfUninitializedVar());
3983+
3984+
return !patternType;
3985+
}
39683986
}
39693987
}
39703988
}

0 commit comments

Comments
 (0)