mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
[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.
This commit is contained in:
@@ -9045,12 +9045,23 @@ ExprWalker::rewriteTarget(SolutionApplicationTarget target) {
|
||||
|
||||
return target;
|
||||
} else if (auto *pattern = target.getAsUninitializedVar()) {
|
||||
TypeResolutionOptions options(TypeResolverContext::PatternBindingDecl);
|
||||
|
||||
auto contextualPattern = target.getContextualPattern();
|
||||
auto patternType = target.getTypeOfUninitializedVar();
|
||||
auto *PB = target.getPatternBindingOfUninitializedVar();
|
||||
|
||||
// If this is a placeholder variable, let's override its type with
|
||||
// inferred one.
|
||||
if (auto *var = PB->getSingleVar()) {
|
||||
if (var->getName().hasDollarPrefix() && patternType->hasPlaceholder()) {
|
||||
patternType = solution.getResolvedType(var);
|
||||
options |= TypeResolutionFlags::OverrideType;
|
||||
}
|
||||
}
|
||||
|
||||
if (auto coercedPattern = TypeChecker::coercePatternToType(
|
||||
contextualPattern, patternType,
|
||||
TypeResolverContext::PatternBindingDecl)) {
|
||||
contextualPattern, patternType, options)) {
|
||||
auto resultTarget = target;
|
||||
resultTarget.setPattern(coercedPattern);
|
||||
return resultTarget;
|
||||
|
||||
@@ -85,6 +85,30 @@ public:
|
||||
}
|
||||
|
||||
inferVariables(type);
|
||||
return {true, expr};
|
||||
}
|
||||
|
||||
auto var = dyn_cast<VarDecl>(decl);
|
||||
if (!var)
|
||||
return {true, expr};
|
||||
|
||||
// If there is no type recorded yet, let's check whether
|
||||
// it is a placeholder variable implicitly generated by the
|
||||
// compiler.
|
||||
if (var->getName().hasDollarPrefix()) {
|
||||
if (auto *PB = var->getParentPatternBinding()) {
|
||||
auto patternTarget = CS.getSolutionApplicationTarget({PB, 0});
|
||||
if (!patternTarget)
|
||||
return {true, expr};
|
||||
|
||||
auto patternType = patternTarget->getTypeOfUninitializedVar();
|
||||
if (patternType->hasPlaceholder()) {
|
||||
auto openedTy = CS.replaceInferableTypesWithTypeVars(
|
||||
patternType, CS.getConstraintLocator(expr));
|
||||
inferVariables(openedTy);
|
||||
CS.setType(var, openedTy);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -521,14 +545,26 @@ private:
|
||||
}
|
||||
|
||||
auto target = getTargetForPattern(patternBinding, index, patternType);
|
||||
if (!target ||
|
||||
cs.generateConstraints(*target, FreeTypeVariableBinding::Disallow)) {
|
||||
if (!target) {
|
||||
hadError = true;
|
||||
return;
|
||||
}
|
||||
|
||||
// Keep track of this binding entry.
|
||||
cs.setSolutionApplicationTarget({patternBinding, index}, *target);
|
||||
|
||||
if (patternType->hasPlaceholder()) {
|
||||
if (auto *var = patternBinding->getSingleVar()) {
|
||||
if (var->getName().hasDollarPrefix() &&
|
||||
!patternBinding->isExplicitlyInitialized(index))
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (cs.generateConstraints(*target, FreeTypeVariableBinding::Disallow)) {
|
||||
hadError = true;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void visitDecl(Decl *decl) {
|
||||
|
||||
@@ -894,6 +894,18 @@ Type ConstraintSystem::replaceInferableTypesWithTypeVars(
|
||||
TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
|
||||
TVO_CanBindToHole);
|
||||
}
|
||||
|
||||
if (auto *var = placeholderTy->getOriginator().dyn_cast<VarDecl *>()) {
|
||||
if (var->getName().hasDollarPrefix()) {
|
||||
auto *repr =
|
||||
new (type->getASTContext()) PlaceholderTypeRepr(var->getLoc());
|
||||
return createTypeVariable(
|
||||
getConstraintLocator(locator,
|
||||
LocatorPathElt::PlaceholderType(repr)),
|
||||
TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
|
||||
TVO_CanBindToHole);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return type;
|
||||
|
||||
Reference in New Issue
Block a user