@@ -491,7 +491,7 @@ struct SyntacticElementContext
491491 }
492492 }
493493
494- bool isSingleExpressionClosure (ConstraintSystem &cs) {
494+ bool isSingleExpressionClosure (ConstraintSystem &cs) const {
495495 if (auto ref = getAsAnyFunctionRef ()) {
496496 if (cs.getAppliedResultBuilderTransform (*ref))
497497 return false ;
@@ -1121,8 +1121,8 @@ class SyntacticElementConstraintGenerator
11211121
11221122 for (auto node : braceStmt->getElements ()) {
11231123 if (auto expr = node.dyn_cast <Expr *>()) {
1124- auto generatedExpr = cs. generateConstraints (
1125- expr, context.getAsDeclContext (), /* isInputExpression= */ false );
1124+ auto generatedExpr =
1125+ cs. generateConstraints ( expr, context.getAsDeclContext ());
11261126 if (!generatedExpr) {
11271127 hadError = true ;
11281128 }
@@ -1248,33 +1248,7 @@ class SyntacticElementConstraintGenerator
12481248 }
12491249
12501250 void visitReturnStmt (ReturnStmt *returnStmt) {
1251- // Single-expression closures are effectively a `return` statement,
1252- // so let's give them a special locator as to indicate that.
1253- // Return statements might not have a result if we have a closure whose
1254- // implicit returned value is coerced to Void.
1255- if (context.isSingleExpressionClosure (cs) && returnStmt->hasResult ()) {
1256- auto *expr = returnStmt->getResult ();
1257- assert (expr && " single expression closure without expression?" );
1258-
1259- expr = cs.generateConstraints (expr, context.getAsDeclContext (),
1260- /* isInputExpression=*/ false );
1261- if (!expr) {
1262- hadError = true ;
1263- return ;
1264- }
1265-
1266- auto contextualResultInfo = getContextualResultInfo ();
1267- cs.addConstraint (ConstraintKind::Conversion, cs.getType (expr),
1268- contextualResultInfo.getType (),
1269- cs.getConstraintLocator (
1270- context.getAsAbstractClosureExpr ().get (),
1271- LocatorPathElt::ClosureBody (
1272- /* hasImpliedReturn=*/ returnStmt->isImplied ())));
1273- return ;
1274- }
1275-
12761251 Expr *resultExpr;
1277-
12781252 if (returnStmt->hasResult ()) {
12791253 resultExpr = returnStmt->getResult ();
12801254 assert (resultExpr && " non-empty result without expression?" );
@@ -1286,10 +1260,10 @@ class SyntacticElementConstraintGenerator
12861260 resultExpr = getVoidExpr (cs.getASTContext (), returnStmt->getEndLoc ());
12871261 }
12881262
1289- auto contextualResultInfo = getContextualResultInfo ();
1263+ auto contextualResultInfo = getContextualResultInfoFor (returnStmt);
1264+
12901265 SyntacticElementTarget target (resultExpr, context.getAsDeclContext (),
1291- contextualResultInfo,
1292- /* isDiscarded=*/ false );
1266+ contextualResultInfo, /* isDiscarded=*/ false );
12931267
12941268 if (cs.generateConstraints (target)) {
12951269 hadError = true ;
@@ -1334,7 +1308,7 @@ class SyntacticElementConstraintGenerator
13341308 createConjunction ({resultElt}, locator);
13351309 }
13361310
1337- ContextualTypeInfo getContextualResultInfo ( ) const {
1311+ ContextualTypeInfo getContextualResultInfoFor (ReturnStmt *returnStmt ) const {
13381312 auto funcRef = AnyFunctionRef::fromDeclContext (context.getAsDeclContext ());
13391313 if (!funcRef)
13401314 return {Type (), CTP_Unused};
@@ -1343,8 +1317,18 @@ class SyntacticElementConstraintGenerator
13431317 return {transform->bodyResultType , CTP_ReturnStmt};
13441318
13451319 if (auto *closure =
1346- getAsExpr<ClosureExpr>(funcRef->getAbstractClosureExpr ()))
1347- return {cs.getClosureType (closure)->getResult (), CTP_ClosureResult};
1320+ getAsExpr<ClosureExpr>(funcRef->getAbstractClosureExpr ())) {
1321+ // Single-expression closures need their contextual type locator anchored
1322+ // on the closure itself. Otherwise we use the default contextual type
1323+ // locator, which will be created for us.
1324+ ConstraintLocator *loc = nullptr ;
1325+ if (context.isSingleExpressionClosure (cs) && returnStmt->hasResult ()) {
1326+ loc = cs.getConstraintLocator (
1327+ closure, {LocatorPathElt::ClosureBody (
1328+ /* hasImpliedReturn=*/ returnStmt->isImplied ())});
1329+ }
1330+ return {cs.getClosureType (closure)->getResult (), CTP_ClosureResult, loc};
1331+ }
13481332
13491333 return {funcRef->getBodyResultType (), CTP_ReturnStmt};
13501334 }
@@ -2162,22 +2146,15 @@ class SyntacticElementSolutionApplication
21622146 mode = convertToResult;
21632147 }
21642148
2165- llvm::Optional<SyntacticElementTarget> resultTarget;
2166- if (auto target = cs.getTargetFor (returnStmt)) {
2167- resultTarget = *target;
2168- } else {
2169- // Single-expression closures have to handle returns in a special
2170- // way so the target has to be created for them during solution
2171- // application based on the resolved type.
2172- assert (context.isSingleExpressionClosure (cs));
2173- resultTarget = SyntacticElementTarget (
2174- resultExpr, context.getAsDeclContext (),
2175- mode == convertToResult ? CTP_ClosureResult : CTP_Unused,
2176- mode == convertToResult ? resultType : Type (),
2177- /* isDiscarded=*/ false );
2178- }
2179-
2180- if (auto newResultTarget = rewriteTarget (*resultTarget)) {
2149+ auto target = *cs.getTargetFor (returnStmt);
2150+
2151+ // If we're not converting to a result, unset the contextual type.
2152+ if (mode != convertToResult) {
2153+ target.setExprConversionType (Type ());
2154+ target.setExprContextualTypePurpose (CTP_Unused);
2155+ }
2156+
2157+ if (auto newResultTarget = rewriteTarget (target)) {
21812158 resultExpr = newResultTarget->getAsExpr ();
21822159 }
21832160
0 commit comments