Skip to content

Commit 432ce1c

Browse files
committed
[ConstraintSystem] Allow placeholder vars to have initializer and nested holes
Initializers of such variables are going to be type-checked post factum, when the type of the variable itself has been determined by the solver.
1 parent a3022b7 commit 432ce1c

File tree

3 files changed

+41
-25
lines changed

3 files changed

+41
-25
lines changed

include/swift/Sema/ConstraintSystem.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6505,6 +6505,13 @@ bool isOperatorDisjunction(Constraint *disjunction);
65056505
/// or nested declarations).
65066506
ASTNode findAsyncNode(ClosureExpr *closure);
65076507

6508+
/// Check whether the given binding represents a placeholder variable that
6509+
/// has to get its type inferred at a first use site.
6510+
///
6511+
/// \returns The currently assigned type if it's a placeholder,
6512+
/// empty type otherwise.
6513+
Type isPlaceholderVar(PatternBindingDecl *PB);
6514+
65086515
} // end namespace constraints
65096516

65106517
template<typename ...Args>

lib/Sema/CSApply.cpp

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9053,11 +9053,9 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
90539053

90549054
// If this is a placeholder variable, let's override its type with
90559055
// inferred one.
9056-
if (auto *var = PB->getSingleVar()) {
9057-
if (var->getName().hasDollarPrefix() && patternType->hasPlaceholder()) {
9058-
patternType = solution.getResolvedType(var);
9059-
options |= TypeResolutionFlags::OverrideType;
9060-
}
9056+
if (isPlaceholderVar(PB)) {
9057+
patternType = solution.getResolvedType(PB->getSingleVar());
9058+
options |= TypeResolutionFlags::OverrideType;
90619059
}
90629060

90639061
if (auto coercedPattern = TypeChecker::coercePatternToType(

lib/Sema/CSClosure.cpp

Lines changed: 31 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -95,19 +95,12 @@ class TypeVariableRefFinder : public ASTWalker {
9595
// If there is no type recorded yet, let's check whether
9696
// it is a placeholder variable implicitly generated by the
9797
// compiler.
98-
if (var->getName().hasDollarPrefix()) {
99-
if (auto *PB = var->getParentPatternBinding()) {
100-
auto patternTarget = CS.getSolutionApplicationTarget({PB, 0});
101-
if (!patternTarget)
102-
return {true, expr};
103-
104-
auto patternType = patternTarget->getTypeOfUninitializedVar();
105-
if (patternType->hasPlaceholder()) {
106-
auto openedTy = CS.replaceInferableTypesWithTypeVars(
107-
patternType, CS.getConstraintLocator(expr));
108-
inferVariables(openedTy);
109-
CS.setType(var, openedTy);
110-
}
98+
if (auto *PB = var->getParentPatternBinding()) {
99+
if (auto placeholderTy = isPlaceholderVar(PB)) {
100+
auto openedTy = CS.replaceInferableTypesWithTypeVars(
101+
placeholderTy, CS.getConstraintLocator(expr));
102+
inferVariables(openedTy);
103+
CS.setType(var, openedTy);
111104
}
112105
}
113106
}
@@ -553,13 +546,8 @@ class SyntacticElementConstraintGenerator
553546
// Keep track of this binding entry.
554547
cs.setSolutionApplicationTarget({patternBinding, index}, *target);
555548

556-
if (patternType->hasPlaceholder()) {
557-
if (auto *var = patternBinding->getSingleVar()) {
558-
if (var->getName().hasDollarPrefix() &&
559-
!patternBinding->isExplicitlyInitialized(index))
560-
return;
561-
}
562-
}
549+
if (isPlaceholderVar(patternBinding))
550+
return;
563551

564552
if (cs.generateConstraints(*target, FreeTypeVariableBinding::Disallow)) {
565553
hadError = true;
@@ -1829,6 +1817,11 @@ void ConjunctionElement::findReferencedVariables(
18291817

18301818
if (auto *patternBinding =
18311819
dyn_cast_or_null<PatternBindingDecl>(element.dyn_cast<Decl *>())) {
1820+
// Let's not walk into placeholder variable initializers, since they
1821+
// are type-checked separately right now.
1822+
if (isPlaceholderVar(patternBinding))
1823+
return;
1824+
18321825
if (auto patternBindingElt =
18331826
locator
18341827
->getLastElementAs<LocatorPathElt::PatternBindingElement>()) {
@@ -1842,3 +1835,21 @@ void ConjunctionElement::findReferencedVariables(
18421835
element.is<Expr *>() || element.isStmt(StmtKind::Return))
18431836
element.walk(refFinder);
18441837
}
1838+
1839+
Type constraints::isPlaceholderVar(PatternBindingDecl *PB) {
1840+
auto *var = PB->getSingleVar();
1841+
if (!var)
1842+
return Type();
1843+
1844+
if (!var->getName().hasDollarPrefix())
1845+
return Type();
1846+
1847+
auto *pattern = PB->getPattern(0);
1848+
if (auto *typedPattern = dyn_cast<TypedPattern>(pattern)) {
1849+
auto type = typedPattern->getType();
1850+
if (type && type->hasPlaceholder())
1851+
return type;
1852+
}
1853+
1854+
return Type();
1855+
}

0 commit comments

Comments
 (0)