Skip to content

Commit b1284d7

Browse files
committed
Used a constraint system, not typeCheckExpression.
1 parent 9e39efb commit b1284d7

File tree

2 files changed

+134
-11
lines changed

2 files changed

+134
-11
lines changed

lib/Sema/TypeCheckStmt.cpp

Lines changed: 21 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
#include "TypeChecker.h"
1818
#include "TypeCheckType.h"
1919
#include "MiscDiagnostics.h"
20+
#include "ConstraintSystem.h"
2021
#include "swift/Subsystems.h"
2122
#include "swift/AST/ASTPrinter.h"
2223
#include "swift/AST/ASTWalker.h"
@@ -1923,7 +1924,8 @@ bool TypeChecker::typeCheckFunctionBodyUntil(FuncDecl *FD,
19231924
// FIXME: FIXME_NOW: DETERMINE: What is the appropriate place for this code to
19241925
// live?
19251926
if (FD->hasSingleExpressionBody()) {
1926-
auto fnType = FD->getBodyResultTypeLoc().getType();
1927+
auto fnTypeLoc = FD->getBodyResultTypeLoc();
1928+
auto fnType = fnTypeLoc.getType();
19271929
auto returnStmt = cast<ReturnStmt>(BS->getElement(0).get<Stmt *>());
19281930
auto E = returnStmt->getResult();
19291931

@@ -1935,7 +1937,7 @@ bool TypeChecker::typeCheckFunctionBodyUntil(FuncDecl *FD,
19351937
// FD->setSingleExpressionBody(E);
19361938
// }
19371939

1938-
if (FD->getBodyResultTypeLoc().isNull() || fnType->isVoid()) {
1940+
if (fnTypeLoc.isNull() || fnType->isVoid()) {
19391941
auto voidExpr = TupleExpr::createEmpty(Context,
19401942
E->getStartLoc(),
19411943
E->getEndLoc(),
@@ -1949,15 +1951,23 @@ bool TypeChecker::typeCheckFunctionBodyUntil(FuncDecl *FD,
19491951
} else {
19501952
// FIXME: FIXME_NOW: DETERMINE: Is this the appropriate mechanism to use
19511953
// to divine the type of E?
1952-
auto exprTy = typeCheckExpression(E, FD, TypeLoc(),
1953-
CTP_ReturnStmt);
1954-
if (!exprTy.isNull() && exprTy->isUninhabited() &&
1955-
exprTy->getCanonicalType() != fnType->getCanonicalType()) {
1956-
BS = BraceStmt::create(Context,
1957-
BS->getStartLoc(),
1958-
{ E },
1959-
BS->getEndLoc(),
1960-
/*implicit=*/true);
1954+
preCheckExpression(E, FD);
1955+
constraints::ConstraintSystem cs(*this, FD,
1956+
constraints::ConstraintSystemFlags::SuppressDiagnostics);
1957+
SmallVector<constraints::Solution, 4> viable;
1958+
if(!cs.solve(E, /*convertType*/Type(), nullptr, viable,
1959+
FreeTypeVariableBinding::Disallow)) {
1960+
auto &solution = viable[0];
1961+
auto &solutionCS = solution.getConstraintSystem();
1962+
Type exprType = solution.simplifyType(solutionCS.getType(E));
1963+
if (!exprType.isNull() && exprType->isUninhabited() &&
1964+
exprType->getCanonicalType() != fnType->getCanonicalType()) {
1965+
BS = BraceStmt::create(Context,
1966+
BS->getStartLoc(),
1967+
{ E },
1968+
BS->getEndLoc(),
1969+
/*implicit=*/true);
1970+
}
19611971
}
19621972
}
19631973
}

test/Parse/omit_return.swift

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,23 @@ func myOwnFatalError() -> MyOwnNever { fatalError() }
3434

3535
func identity<T>(_ t: T) -> T { t }
3636

37+
internal func _fatalErrorFlags() -> UInt32 {
38+
return 0
39+
}
40+
internal func _assertionFailure(
41+
_ prefix: StaticString, _ message: String,
42+
flags: UInt32
43+
) -> Never {
44+
fatalError()
45+
}
46+
internal func _diagnoseUnexpectedEnumCaseValue<SwitchedValue, RawValue>(
47+
type: SwitchedValue.Type,
48+
rawValue: RawValue
49+
) -> Never {
50+
_assertionFailure("Fatal error",
51+
"unexpected enum case '\(type)(rawValue: \(rawValue))'",
52+
flags: _fatalErrorFlags())
53+
}
3754

3855

3956
// MARK: - Free Functions
@@ -62,6 +79,22 @@ func ff_implicitClosure() -> () -> Void {
6279
{ print("howdy") }
6380
}
6481

82+
func ff_explicitMultilineClosure() -> () -> String {
83+
return {
84+
let one = "big a"
85+
let two = "little a"
86+
return "\(one) + \(two)"
87+
}
88+
}
89+
90+
func ff_implicitMultilineClosure() -> () -> String {
91+
{
92+
let one = "big a"
93+
let two = "little a"
94+
return "\(one) + \(two)"
95+
}
96+
}
97+
6598
func ff_implicitWrong() -> String {
6699
17 // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
67100
}
@@ -242,6 +275,22 @@ var fv_implicitClosure: () -> Void {
242275
{ print("howdy") }
243276
}
244277

278+
var fv_explicitMultilineClosure: () -> String {
279+
return {
280+
let one = "big a"
281+
let two = "little a"
282+
return "\(one) + \(two)"
283+
}
284+
}
285+
286+
var fv_implicitMultilineClosure: () -> String {
287+
{
288+
let one = "big a"
289+
let two = "little a"
290+
return "\(one) + \(two)"
291+
}
292+
}
293+
245294
var fv_implicitWrong: String {
246295
17 // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
247296
}
@@ -400,6 +449,26 @@ var fvg_implicitClosure: () -> Void {
400449
}
401450
}
402451

452+
var fvg_explicitMultilineClosure: () -> String {
453+
get {
454+
return {
455+
let one = "big a"
456+
let two = "little a"
457+
return "\(one) + \(two)"
458+
}
459+
}
460+
}
461+
462+
var fvg_implicitMultilineClosure: () -> String {
463+
get {
464+
{
465+
let one = "big a"
466+
let two = "little a"
467+
return "\(one) + \(two)"
468+
}
469+
}
470+
}
471+
403472
var fvg_implicitWrong: String {
404473
get {
405474
17 // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
@@ -726,6 +795,26 @@ enum S_implicitClosure {
726795
}
727796
}
728797

798+
enum S_explicitMultilineClosure {
799+
subscript() -> () -> String {
800+
return {
801+
let one = "big a"
802+
let two = "little a"
803+
return "\(one) + \(two)"
804+
}
805+
}
806+
}
807+
808+
enum S_implicitMultilineClosure {
809+
subscript() -> () -> String {
810+
{
811+
let one = "big a"
812+
let two = "little a"
813+
return "\(one) + \(two)"
814+
}
815+
}
816+
}
817+
729818
enum S_implicitWrong {
730819
subscript() -> String {
731820
17 // expected-error {{cannot convert return expression of type 'Int' to return type 'String'}}
@@ -932,6 +1021,30 @@ enum SRO_implicitClosure {
9321021
}
9331022
}
9341023

1024+
enum SRO_explicitMultilineClosure {
1025+
subscript() -> () -> String {
1026+
get {
1027+
return {
1028+
let one = "big a"
1029+
let two = "little a"
1030+
return "\(one) + \(two)"
1031+
}
1032+
}
1033+
}
1034+
}
1035+
1036+
enum SRO_implicitMultilineClosure {
1037+
subscript() -> () -> String {
1038+
get {
1039+
{
1040+
let one = "big a"
1041+
let two = "little a"
1042+
return "\(one) + \(two)"
1043+
}
1044+
}
1045+
}
1046+
}
1047+
9351048
enum SRO_implicitWrong {
9361049
subscript() -> String {
9371050
get {

0 commit comments

Comments
 (0)