Skip to content

Commit ff0c942

Browse files
xedinahoppen
authored andcommitted
[CSSyntacticElement] Fix solution applicator to identify context correctly
`TapExpr` do not form their own declaration context which means that using `context.getAsDeclContext` is incorrect for them.
1 parent 4b091be commit ff0c942

File tree

1 file changed

+32
-15
lines changed

1 file changed

+32
-15
lines changed

lib/Sema/CSSyntacticElement.cpp

Lines changed: 32 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1645,7 +1645,6 @@ class SyntacticElementSolutionApplication
16451645
protected:
16461646
Solution &solution;
16471647
SyntacticElementContext context;
1648-
Type resultType;
16491648
RewriteTargetFn rewriteTarget;
16501649

16511650
/// All `func`s declared in the body of the closure.
@@ -1658,24 +1657,39 @@ class SyntacticElementSolutionApplication
16581657
SyntacticElementSolutionApplication(Solution &solution,
16591658
SyntacticElementContext context,
16601659
RewriteTargetFn rewriteTarget)
1661-
: solution(solution), context(context), rewriteTarget(rewriteTarget) {
1662-
if (auto fn = AnyFunctionRef::fromDeclContext(context.getAsDeclContext())) {
1660+
: solution(solution), context(context), rewriteTarget(rewriteTarget) {}
1661+
1662+
virtual ~SyntacticElementSolutionApplication() {}
1663+
1664+
private:
1665+
Type getContextualResultType() const {
1666+
// Taps do not have a contextual result type.
1667+
if (context.is<TapExpr *>()) {
1668+
return Type();
1669+
}
1670+
1671+
auto fn = context.getAsAnyFunctionRef();
1672+
1673+
if (context.is<SingleValueStmtExpr *>()) {
1674+
// if/switch expressions can have `return` inside.
1675+
fn = AnyFunctionRef::fromDeclContext(context.getAsDeclContext());
1676+
}
1677+
1678+
if (fn) {
16631679
if (auto transform = solution.getAppliedBuilderTransform(*fn)) {
1664-
resultType = solution.simplifyType(transform->bodyResultType);
1680+
return solution.simplifyType(transform->bodyResultType);
16651681
} else if (auto *closure =
16661682
getAsExpr<ClosureExpr>(fn->getAbstractClosureExpr())) {
1667-
resultType = solution.getResolvedType(closure)
1668-
->castTo<FunctionType>()
1669-
->getResult();
1683+
return solution.getResolvedType(closure)
1684+
->castTo<FunctionType>()
1685+
->getResult();
16701686
} else {
1671-
resultType = fn->getBodyResultType();
1687+
return fn->getBodyResultType();
16721688
}
16731689
}
1674-
}
1675-
1676-
virtual ~SyntacticElementSolutionApplication() {}
16771690

1678-
private:
1691+
return Type();
1692+
}
16791693

16801694
ASTNode visit(Stmt *S, bool performSyntacticDiagnostics = true) {
16811695
auto rewritten = ASTVisitor::visit(S);
@@ -2031,17 +2045,18 @@ class SyntacticElementSolutionApplication
20312045
auto closure = context.getAsAbstractClosureExpr();
20322046
if (closure && !closure.get()->hasSingleExpressionBody() &&
20332047
closure.get()->getBody() == braceStmt) {
2048+
auto resultType = getContextualResultType();
20342049
if (resultType->getOptionalObjectType() &&
20352050
resultType->lookThroughAllOptionalTypes()->isVoid() &&
20362051
!braceStmt->getLastElement().isStmt(StmtKind::Return)) {
2037-
return addImplicitVoidReturn(braceStmt);
2052+
return addImplicitVoidReturn(braceStmt, resultType);
20382053
}
20392054
}
20402055

20412056
return braceStmt;
20422057
}
20432058

2044-
ASTNode addImplicitVoidReturn(BraceStmt *braceStmt) {
2059+
ASTNode addImplicitVoidReturn(BraceStmt *braceStmt, Type contextualResultTy) {
20452060
auto &cs = solution.getConstraintSystem();
20462061
auto &ctx = cs.getASTContext();
20472062

@@ -2056,7 +2071,7 @@ class SyntacticElementSolutionApplication
20562071
// number of times.
20572072
{
20582073
SyntacticElementTarget target(resultExpr, context.getAsDeclContext(),
2059-
CTP_ReturnStmt, resultType,
2074+
CTP_ReturnStmt, contextualResultTy,
20602075
/*isDiscarded=*/false);
20612076
cs.setTargetFor(returnStmt, target);
20622077

@@ -2077,6 +2092,8 @@ class SyntacticElementSolutionApplication
20772092
ASTNode visitReturnStmt(ReturnStmt *returnStmt) {
20782093
auto &cs = solution.getConstraintSystem();
20792094

2095+
auto resultType = getContextualResultType();
2096+
20802097
if (!returnStmt->hasResult()) {
20812098
// If contextual is not optional, there is nothing to do here.
20822099
if (resultType->isVoid())

0 commit comments

Comments
 (0)