Revert "Revert "A couple of 'throws' inference fix-ups:""

This reverts commit r27576.

(In some cases of catastrophic error recovery, ctor types may still be null during constraint solving, so it was wrong of me to assume otherwise.)

Swift SVN r27599
This commit is contained in:
Joe Pamer
2015-04-22 20:34:05 +00:00
parent b0497db5ec
commit 220c92a09b
3 changed files with 32 additions and 4 deletions

View File

@@ -1699,8 +1699,10 @@ namespace {
std::pair<bool, Stmt *> walkToStmtPre(Stmt *stmt) override {
// Do not walk into 'do' clauses.
if (dyn_cast<DoStmt>(stmt)) {
// Do not walk into the 'do' clause of a do/catch statement.
if (dyn_cast<BraceStmt>(stmt) &&
Parent.getAsStmt() &&
dyn_cast<DoCatchStmt>(Parent.getAsStmt())) {
return { false, stmt };
}

View File

@@ -2247,6 +2247,21 @@ ConstraintSystem::simplifyConstructionConstraint(Type valueType,
return SolutionKind::Error;
}
auto extInfo = FunctionType::ExtInfo();
// Check to see if the initializer's overload group throws.
for (auto ctor : ctors) {
if (ctor->getType() && ctor->getType()->getAs<AnyFunctionType>()) {
if (auto innerFnTy = ctor->getType()->getAs<AnyFunctionType>()->
getResult()->getAs<AnyFunctionType>()) {
if (innerFnTy->throws()) {
extInfo = extInfo.withThrows();
break;
}
}
}
}
auto &context = getASTContext();
auto name = context.Id_init;
auto applyLocator = getConstraintLocator(locator,
@@ -2258,7 +2273,7 @@ ConstraintSystem::simplifyConstructionConstraint(Type valueType,
// variable T. T2 is the result type provided via the construction
// constraint itself.
addValueMemberConstraint(valueType, name,
FunctionType::get(tv, resultType),
FunctionType::get(tv, resultType, extInfo),
getConstraintLocator(
locator,
ConstraintLocator::ConstructorMember));

View File

@@ -103,8 +103,19 @@ func testSubtypeArgument2(x1: (fn: (String -> Int)) -> Int,
// Closures
var c1 = {() throws -> Int in 0}
var c2 : () throws -> Int = c1 // ok
var c3 : () -> Int = c1 // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c4 : () -> Int = {() throws -> Int in 0} // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c5 : () -> Int = { try 0 } // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c6 : () throws -> Int = { do { try 0 } ; return 0 }
var c7 : () -> Int = { do { try 0 } ; return 0 } // expected-error{{invalid conversion from throwing function of type '() throws -> Int' to non-throwing function type '() -> Int'}}
var c8 : () -> Int = { do { try 0 } catch _ { var x = 0 } ; return 0 }
// Initializers
struct A {
init(doomed: ()) throws {}
}
func fi1() throws {
A(doomed: ())
}