Skip to content

Commit 1003b2f

Browse files
committed
[CS] Remove CTP_ImpliedReturnStmt
Unify with `CTP_ReturnStmt`, and have the SyntacticElementTarget carry the ReturnStmt for regular type-checking, which we can use to record implied returns.
1 parent d7fc22a commit 1003b2f

12 files changed

+50
-52
lines changed

include/swift/Sema/ConstraintLocator.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,6 @@ enum ContextualTypePurpose : uint8_t {
5050
CTP_Unused, ///< No contextual type is specified.
5151
CTP_Initialization, ///< Pattern binding initialization.
5252
CTP_ReturnStmt, ///< Value specified to a 'return' statement.
53-
CTP_ImpliedReturnStmt, ///< Value from an implied 'return', e.g a single expr
54-
/// function body.
5553
CTP_YieldByValue, ///< By-value yield operand.
5654
CTP_YieldByReference, ///< By-reference yield operand.
5755
CTP_ThrowStmt, ///< Value specified to a 'throw' statement.

include/swift/Sema/ConstraintSystem.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1469,8 +1469,8 @@ struct PotentialThrowSite {
14691469
};
14701470

14711471
enum class ImpliedResultKind {
1472-
/// A regular implied result, this applies to e.g implied 'then' statements
1473-
/// outside of closures.
1472+
/// A regular implied result, this applies to e.g single expression bodies of
1473+
/// function decls, and implied 'then' statements outside of closures.
14741474
Regular,
14751475

14761476
/// An implied result for a closure, e.g a single expression body.

include/swift/Sema/SyntacticElementTarget.h

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,9 @@ class SyntacticElementTarget {
9191
/// pattern.
9292
Pattern *pattern;
9393

94+
/// The parent return statement if any.
95+
ReturnStmt *parentReturnStmt;
96+
9497
struct {
9598
/// The variable to which property wrappers have been applied, if
9699
/// this is an initialization involving a property wrapper.
@@ -261,6 +264,10 @@ class SyntacticElementTarget {
261264
PatternBindingDecl *patternBinding,
262265
unsigned patternBindingIndex, bool bindPatternVarsOneWay);
263266

267+
/// Form an expression target for a ReturnStmt.
268+
static SyntacticElementTarget
269+
forReturn(ReturnStmt *returnStmt, Type contextTy, DeclContext *dc);
270+
264271
/// Form a target for a for-in loop.
265272
static SyntacticElementTarget
266273
forForEachStmt(ForEachStmt *stmt, DeclContext *dc,
@@ -457,6 +464,11 @@ class SyntacticElementTarget {
457464
return cast<ExprPattern>(expression.pattern);
458465
}
459466

467+
ReturnStmt *getParentReturnStmt() const {
468+
assert(kind == Kind::expression);
469+
return expression.parentReturnStmt;
470+
}
471+
460472
Type getClosureContextualType() const {
461473
assert(kind == Kind::closure);
462474
return closure.convertType;

lib/IDE/TypeCheckCompletionCallback.cpp

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -156,10 +156,6 @@ void WithSolutionSpecificVarTypesRAII::setInterfaceType(VarDecl *VD, Type Ty) {
156156
}
157157

158158
bool swift::ide::isImpliedResult(const Solution &S, Expr *CompletionExpr) {
159-
auto &CS = S.getConstraintSystem();
160-
if (CS.getContextualTypePurpose(CompletionExpr) == CTP_ImpliedReturnStmt)
161-
return true;
162-
163159
return S.isImpliedResult(CompletionExpr).has_value();
164160
}
165161

lib/Sema/CSApply.cpp

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9430,7 +9430,6 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
94309430
case CTP_ExprPattern:
94319431
case CTP_ForEachStmt:
94329432
case CTP_ForEachSequence:
9433-
case CTP_ImpliedReturnStmt:
94349433
case CTP_YieldByValue:
94359434
case CTP_YieldByReference:
94369435
case CTP_ThrowStmt:
@@ -9637,8 +9636,7 @@ ExprWalker::rewriteTarget(SyntacticElementTarget target) {
96379636

96389637
if (solution.simplifyType(convertType)->isVoid()) {
96399638
auto contextPurpose = cs.getContextualTypePurpose(target.getAsExpr());
9640-
if (contextPurpose == CTP_ImpliedReturnStmt ||
9641-
contextPurpose == CTP_ClosureResult ||
9639+
if (contextPurpose == CTP_ClosureResult ||
96429640
contextPurpose == CTP_SingleValueStmtBranch) {
96439641
return false;
96449642
}

lib/Sema/CSDiagnostics.cpp

Lines changed: 3 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -306,10 +306,8 @@ ValueDecl *RequirementFailure::getDeclRef() const {
306306
// and its contextual requirements, it means that affected declaration
307307
// is a declarer of a contextual "result" type e.g. member of a
308308
// type, local function etc.
309-
if (contextualPurpose == CTP_ReturnStmt ||
310-
contextualPurpose == CTP_ImpliedReturnStmt) {
309+
if (contextualPurpose == CTP_ReturnStmt)
311310
return cast<ValueDecl>(getDC()->getAsDecl());
312-
}
313311

314312
if (contextualPurpose == CTP_DefaultParameter ||
315313
contextualPurpose == CTP_AutoclosureDefaultParameter) {
@@ -772,7 +770,6 @@ GenericArgumentsMismatchFailure::getDiagnosticFor(
772770
case CTP_AssignSource:
773771
return diag::cannot_convert_assign;
774772
case CTP_ReturnStmt:
775-
case CTP_ImpliedReturnStmt:
776773
return diag::cannot_convert_to_return_type;
777774
case CTP_DefaultParameter:
778775
case CTP_AutoclosureDefaultParameter:
@@ -2483,7 +2480,7 @@ bool ContextualFailure::diagnoseAsError() {
24832480
auto anchor = getAnchor();
24842481
auto path = getLocator()->getPath();
24852482

2486-
if (CTP == CTP_ImpliedReturnStmt || CTP == CTP_ReturnStmt) {
2483+
if (CTP == CTP_ReturnStmt) {
24872484
// Special case the "conversion to void".
24882485
if (getToType()->isVoid()) {
24892486
emitDiagnostic(diag::cannot_return_value_from_void_func)
@@ -2824,7 +2821,6 @@ getContextualNilDiagnostic(ContextualTypePurpose CTP) {
28242821
case CTP_Initialization:
28252822
return diag::cannot_convert_initializer_value_nil;
28262823

2827-
case CTP_ImpliedReturnStmt:
28282824
case CTP_ReturnStmt:
28292825
return diag::cannot_convert_to_return_type_nil;
28302826

@@ -3568,8 +3564,7 @@ ContextualFailure::getDiagnosticFor(ContextualTypePurpose context,
35683564
return forProtocol ? diag::cannot_convert_initializer_value_protocol
35693565
: diag::cannot_convert_initializer_value;
35703566
}
3571-
case CTP_ReturnStmt:
3572-
case CTP_ImpliedReturnStmt: {
3567+
case CTP_ReturnStmt: {
35733568
if (contextualType->isAnyObject())
35743569
return diag::cannot_convert_return_type_to_anyobject;
35753570

lib/Sema/CSGen.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4771,6 +4771,12 @@ bool ConstraintSystem::generateConstraints(
47714771
target.setExprConversionType(TypeChecker::getOptionalType(expr->getLoc(), var));
47724772
}
47734773

4774+
// If we have a parent return statement, record whether it's implied.
4775+
if (auto *RS = target.getParentReturnStmt()) {
4776+
if (RS->isImplied())
4777+
recordImpliedResult(expr, ImpliedResultKind::Regular);
4778+
}
4779+
47744780
expr = buildTypeErasedExpr(expr, target.getDeclContext(),
47754781
target.getExprContextualType(),
47764782
target.getExprContextualTypePurpose());

lib/Sema/CSSimplify.cpp

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -6077,8 +6077,7 @@ bool ConstraintSystem::repairFailures(
60776077
return true;
60786078

60796079
auto purpose = getContextualTypePurpose(anchor);
6080-
if (rhs->isVoid() &&
6081-
(purpose == CTP_ReturnStmt || purpose == CTP_ImpliedReturnStmt)) {
6080+
if (rhs->isVoid() && purpose == CTP_ReturnStmt) {
60826081
conversionsOrFixes.push_back(
60836082
RemoveReturn::create(*this, lhs, getConstraintLocator(locator)));
60846083
return true;
@@ -7859,14 +7858,6 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
78597858
if (auto elt = locator.last()) {
78607859
if (kind >= ConstraintKind::Subtype &&
78617860
(type1->isUninhabited() || type2->isVoid())) {
7862-
// Function with an implied `return`, e.g a single expression body.
7863-
if (auto contextualType = elt->getAs<LocatorPathElt::ContextualType>()) {
7864-
if (contextualType->isFor(CTP_ImpliedReturnStmt)) {
7865-
increaseScore(SK_FunctionConversion, locator);
7866-
return getTypeMatchSuccess();
7867-
}
7868-
}
7869-
78707861
// Implied results can occur for closure bodies, returns, and if/switch
78717862
// expression branches.
78727863
//
@@ -7877,6 +7868,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
78777868
// Never conversion.
78787869
auto *loc = getConstraintLocator(locator);
78797870
if (elt->is<LocatorPathElt::ClosureBody>() ||
7871+
loc->isForContextualType(CTP_ReturnStmt) ||
78807872
loc->isForContextualType(CTP_ClosureResult) ||
78817873
loc->isForSingleValueStmtBranch()) {
78827874
bool allowConversion = false;
@@ -15599,7 +15591,6 @@ void ConstraintSystem::addContextualConversionConstraint(
1559915591
auto constraintKind = ConstraintKind::Conversion;
1560015592
switch (purpose) {
1560115593
case CTP_ReturnStmt:
15602-
case CTP_ImpliedReturnStmt:
1560315594
case CTP_Initialization: {
1560415595
if (conversionType->is<OpaqueTypeArchetypeType>())
1560515596
constraintKind = ConstraintKind::Equal;

lib/Sema/ConstraintSystem.cpp

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1217,15 +1217,11 @@ Type ConstraintSystem::openOpaqueType(Type type, ContextualTypePurpose context,
12171217
if (!type || !type->hasOpaqueArchetype())
12181218
return type;
12191219

1220-
auto inReturnContext = [](ContextualTypePurpose context) {
1221-
return context == CTP_ReturnStmt || context == CTP_ImpliedReturnStmt;
1222-
};
1223-
1224-
if (!(context == CTP_Initialization || inReturnContext(context)))
1220+
if (!(context == CTP_Initialization || context == CTP_ReturnStmt))
12251221
return type;
12261222

12271223
auto shouldOpen = [&](OpaqueTypeArchetypeType *opaqueType) {
1228-
if (!inReturnContext(context))
1224+
if (context != CTP_ReturnStmt)
12291225
return true;
12301226

12311227
if (auto *func = dyn_cast<AbstractFunctionDecl>(DC))
@@ -7034,7 +7030,7 @@ Expr *ConstraintSystem::buildAutoClosureExpr(Expr *expr,
70347030
Expr *ConstraintSystem::buildTypeErasedExpr(Expr *expr, DeclContext *dc,
70357031
Type contextualType,
70367032
ContextualTypePurpose purpose) {
7037-
if (!(purpose == CTP_ReturnStmt || purpose == CTP_ImpliedReturnStmt))
7033+
if (purpose != CTP_ReturnStmt)
70387034
return expr;
70397035

70407036
auto *decl = dyn_cast_or_null<ValueDecl>(dc->getAsDecl());

lib/Sema/MiscDiagnostics.cpp

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3863,7 +3863,6 @@ class SingleValueStmtUsageChecker final : public ASTWalker {
38633863
// Allowed in returns, throws, and bindings.
38643864
switch (ctp) {
38653865
case CTP_ReturnStmt:
3866-
case CTP_ImpliedReturnStmt:
38673866
case CTP_ThrowStmt:
38683867
case CTP_Initialization:
38693868
markValidSingleValueStmt(E);

0 commit comments

Comments
 (0)