@@ -1712,17 +1712,12 @@ namespace {
17121712 const auto result = TypeResolution::resolveContextualType (
17131713 repr, CS.DC , options, genericOpener, placeholderHandler,
17141714 packElementOpener, requirementOpener);
1715+ // If we have an error, record a fix and produce a hole for the type.
17151716 if (result->hasError ()) {
17161717 CS.recordFix (
17171718 IgnoreInvalidASTNode::create (CS, CS.getConstraintLocator (locator)));
17181719
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);
17261721 }
17271722 // Diagnose top-level usages of placeholder types.
17281723 if (auto *ty = dyn_cast<PlaceholderTypeRepr>(repr->getWithoutParens ())) {
@@ -4901,18 +4896,6 @@ bool ConstraintSystem::generateConstraints(
49014896 getConstraintLocator (expr, LocatorPathElt::ContextualType (ctp));
49024897 }
49034898
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-
49164899 // If the contextual type has an error, we can't apply the solution.
49174900 // Record a fix for an invalid AST node.
49184901 if (convertType->hasError ())
@@ -4921,18 +4904,30 @@ bool ConstraintSystem::generateConstraints(
49214904 // Substitute type variables in for placeholder and error types.
49224905 convertType =
49234906 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);
49344924 }
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 ;
49364931 });
49374932
49384933 addContextualConversionConstraint (expr, convertType, ctp,
0 commit comments