@@ -1712,17 +1712,12 @@ namespace {
1712
1712
const auto result = TypeResolution::resolveContextualType (
1713
1713
repr, CS.DC , options, genericOpener, placeholderHandler,
1714
1714
packElementOpener, requirementOpener);
1715
+ // If we have an error, record a fix and produce a hole for the type.
1715
1716
if (result->hasError ()) {
1716
1717
CS.recordFix (
1717
1718
IgnoreInvalidASTNode::create (CS, CS.getConstraintLocator (locator)));
1718
1719
1719
- // Immediately bind the result to a hole since we know it's invalid and
1720
- // want it to propagate rather than allowing other type variables to
1721
- // become holes.
1722
- auto *tv = CS.createTypeVariable (CS.getConstraintLocator (repr),
1723
- TVO_CanBindToHole);
1724
- CS.recordTypeVariablesAsHoles (tv);
1725
- return tv;
1720
+ return PlaceholderType::get (CS.getASTContext (), repr);
1726
1721
}
1727
1722
// Diagnose top-level usages of placeholder types.
1728
1723
if (auto *ty = dyn_cast<PlaceholderTypeRepr>(repr->getWithoutParens ())) {
@@ -4901,18 +4896,6 @@ bool ConstraintSystem::generateConstraints(
4901
4896
getConstraintLocator (expr, LocatorPathElt::ContextualType (ctp));
4902
4897
}
4903
4898
4904
- auto getLocator = [&](Type ty) -> ConstraintLocator * {
4905
- // If we have a placeholder originating from a PlaceholderTypeRepr,
4906
- // tack that on to the locator.
4907
- if (auto *placeholderTy = ty->getAs <PlaceholderType>())
4908
- if (auto *typeRepr = placeholderTy->getOriginator ()
4909
- .dyn_cast <TypeRepr *>())
4910
- return getConstraintLocator (
4911
- convertTypeLocator,
4912
- LocatorPathElt::PlaceholderType (typeRepr));
4913
- return convertTypeLocator;
4914
- };
4915
-
4916
4899
// If the contextual type has an error, we can't apply the solution.
4917
4900
// Record a fix for an invalid AST node.
4918
4901
if (convertType->hasError ())
@@ -4921,18 +4904,30 @@ bool ConstraintSystem::generateConstraints(
4921
4904
// Substitute type variables in for placeholder and error types.
4922
4905
convertType =
4923
4906
convertType.transformRec ([&](Type type) -> std::optional<Type> {
4924
- if (!isa<PlaceholderType, ErrorType>(type.getPointer ()))
4925
- return std::nullopt ;
4926
-
4927
- auto flags = TVO_CanBindToNoEscape | TVO_PrefersSubtypeBinding |
4928
- TVO_CanBindToHole;
4929
- auto tv = Type (createTypeVariable (getLocator (type), flags));
4930
- // For ErrorTypes we want to eagerly bind to a hole since we
4931
- // know this is where the issue is.
4932
- if (isa<ErrorType>(type.getPointer ())) {
4933
- recordTypeVariablesAsHoles (tv);
4907
+ auto *tyPtr = type.getPointer ();
4908
+ // Open a type variable for a placeholder type repr. Note we don't
4909
+ // do this for arbitrary placeholders since they may be existing
4910
+ // holes when e.g generating the constraints for a ReturnStmt in a
4911
+ // closure.
4912
+ if (auto *placeholderTy = dyn_cast<PlaceholderType>(tyPtr)) {
4913
+ auto originator = placeholderTy->getOriginator ();
4914
+ auto *typeRepr = originator.dyn_cast <TypeRepr *>();
4915
+ if (!isa_and_nonnull<PlaceholderTypeRepr>(typeRepr))
4916
+ return std::nullopt ;
4917
+
4918
+ auto *loc = getConstraintLocator (
4919
+ convertTypeLocator,
4920
+ LocatorPathElt::PlaceholderType (typeRepr));
4921
+ return createTypeVariable (loc, TVO_CanBindToNoEscape |
4922
+ TVO_PrefersSubtypeBinding |
4923
+ TVO_CanBindToHole);
4934
4924
}
4935
- return tv;
4925
+ // For ErrorTypes we want to eagerly produce a hole since we know
4926
+ // this is where the issue is.
4927
+ if (auto *errTy = dyn_cast<ErrorType>(tyPtr)) {
4928
+ return PlaceholderType::get (getASTContext (), errTy);
4929
+ }
4930
+ return std::nullopt ;
4936
4931
});
4937
4932
4938
4933
addContextualConversionConstraint (expr, convertType, ctp,
0 commit comments