Skip to content

Commit a6421fc

Browse files
committed
[CSClosure] Declarations prefixed with $ can act as inferrable placeholders
If the type for such declaration could be completely inferred it would be used during solution application. This is used to infer types for result builder components.
1 parent 65aeb4a commit a6421fc

File tree

3 files changed

+63
-4
lines changed

3 files changed

+63
-4
lines changed

lib/Sema/CSApply.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9045,12 +9045,23 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
90459045

90469046
return target;
90479047
} else if (auto *pattern = target.getAsUninitializedVar()) {
9048+
TypeResolutionOptions options(TypeResolverContext::PatternBindingDecl);
9049+
90489050
auto contextualPattern = target.getContextualPattern();
90499051
auto patternType = target.getTypeOfUninitializedVar();
9052+
auto *PB = target.getPatternBindingOfUninitializedVar();
9053+
9054+
// If this is a placeholder variable, let's override its type with
9055+
// 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+
}
9061+
}
90509062

90519063
if (auto coercedPattern = TypeChecker::coercePatternToType(
9052-
contextualPattern, patternType,
9053-
TypeResolverContext::PatternBindingDecl)) {
9064+
contextualPattern, patternType, options)) {
90549065
auto resultTarget = target;
90559066
resultTarget.setPattern(coercedPattern);
90569067
return resultTarget;

lib/Sema/CSClosure.cpp

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,30 @@ class TypeVariableRefFinder : public ASTWalker {
8585
}
8686

8787
inferVariables(type);
88+
return {true, expr};
89+
}
90+
91+
auto var = dyn_cast<VarDecl>(decl);
92+
if (!var)
93+
return {true, expr};
94+
95+
// If there is no type recorded yet, let's check whether
96+
// it is a placeholder variable implicitly generated by the
97+
// 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+
}
111+
}
88112
}
89113
}
90114

@@ -521,14 +545,26 @@ class SyntacticElementConstraintGenerator
521545
}
522546

523547
auto target = getTargetForPattern(patternBinding, index, patternType);
524-
if (!target ||
525-
cs.generateConstraints(*target, FreeTypeVariableBinding::Disallow)) {
548+
if (!target) {
526549
hadError = true;
527550
return;
528551
}
529552

530553
// Keep track of this binding entry.
531554
cs.setSolutionApplicationTarget({patternBinding, index}, *target);
555+
556+
if (patternType->hasPlaceholder()) {
557+
if (auto *var = patternBinding->getSingleVar()) {
558+
if (var->getName().hasDollarPrefix() &&
559+
!patternBinding->isExplicitlyInitialized(index))
560+
return;
561+
}
562+
}
563+
564+
if (cs.generateConstraints(*target, FreeTypeVariableBinding::Disallow)) {
565+
hadError = true;
566+
return;
567+
}
532568
}
533569

534570
void visitDecl(Decl *decl) {

lib/Sema/ConstraintSystem.cpp

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -894,6 +894,18 @@ Type ConstraintSystem::replaceInferableTypesWithTypeVars(
894894
TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
895895
TVO_CanBindToHole);
896896
}
897+
898+
if (auto *var = placeholderTy->getOriginator().dyn_cast<VarDecl *>()) {
899+
if (var->getName().hasDollarPrefix()) {
900+
auto *repr =
901+
new (type->getASTContext()) PlaceholderTypeRepr(var->getLoc());
902+
return createTypeVariable(
903+
getConstraintLocator(locator,
904+
LocatorPathElt::PlaceholderType(repr)),
905+
TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
906+
TVO_CanBindToHole);
907+
}
908+
}
897909
}
898910

899911
return type;

0 commit comments

Comments
 (0)