Skip to content

Commit a1de698

Browse files
committed
---
yaml --- r: 346095 b: refs/heads/master c: 65483f4 h: refs/heads/master i: 346093: 2d33ca8 346091: 058dbc1 346087: 2e613a5 346079: 02acfbf
1 parent 9e566a8 commit a1de698

File tree

4 files changed

+43
-3
lines changed

4 files changed

+43
-3
lines changed

[refs]

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
refs/heads/master: cd417213a7faf267ec1f4a94886246fa5b6337e4
2+
refs/heads/master: 65483f43aeb5a15c6a25c23df90acaed106b45a2
33
refs/heads/master-next: 203b3026584ecad859eb328b2e12490099409cd5
44
refs/tags/osx-passed: b6b74147ef8a386f532cf9357a1bde006e552c54
55
refs/tags/swift-2.2-SNAPSHOT-2015-12-01-a: 6bb18e013c2284f2b45f5f84f2df2887dc0f7dea

trunk/lib/Sema/CSBindings.cpp

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -389,6 +389,7 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
389389
auto &tc = getTypeChecker();
390390
bool hasNonDependentMemberRelationalConstraints = false;
391391
bool hasDependentMemberRelationalConstraints = false;
392+
bool sawNilLiteral = false;
392393
for (auto constraint : constraints) {
393394
switch (constraint->getKind()) {
394395
case ConstraintKind::Bind:
@@ -505,8 +506,10 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
505506
// If there is a 'nil' literal constraint, we might need optional
506507
// supertype bindings.
507508
if (constraint->getProtocol()->isSpecificProtocol(
508-
KnownProtocolKind::ExpressibleByNilLiteral))
509+
KnownProtocolKind::ExpressibleByNilLiteral)) {
510+
sawNilLiteral = true;
509511
addOptionalSupertypeBindings = true;
512+
}
510513

511514
// If there is a default literal type for this protocol, it's a
512515
// potential binding.
@@ -745,6 +748,32 @@ ConstraintSystem::getPotentialBindings(TypeVariableType *typeVar) {
745748
result.Bindings.clear();
746749
}
747750

751+
// Revise any optional-of-function-types we may try to nil literals
752+
// to be non-throwing so they don't inadvertantly result in rethrows
753+
// diagnostics.
754+
if (sawNilLiteral) {
755+
for (auto &binding : result.Bindings) {
756+
auto nested = binding.BindingType->lookThroughAllOptionalTypes();
757+
if (!nested)
758+
continue;
759+
760+
if (!nested->is<FunctionType>())
761+
continue;
762+
763+
// Remove throws from the nested function type.
764+
binding.BindingType =
765+
binding.BindingType.transform([&](Type inner) -> Type {
766+
auto *fnTy = dyn_cast<FunctionType>(inner.getPointer());
767+
if (!fnTy)
768+
return inner;
769+
770+
auto extInfo = fnTy->getExtInfo().withThrows(false);
771+
return FunctionType::get(fnTy->getParams(), fnTy->getResult(),
772+
extInfo);
773+
});
774+
}
775+
}
776+
748777
return result;
749778
}
750779

trunk/lib/Sema/TypeCheckError.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,9 @@ class AbstractFunction {
146146
// Look through closure capture lists.
147147
} else if (auto captureList = dyn_cast<CaptureListExpr>(fn)) {
148148
fn = captureList->getClosureBody();
149+
// Look through optional evaluations.
150+
} else if (auto optionalEval = dyn_cast<OptionalEvaluationExpr>(fn)) {
151+
fn = optionalEval->getSubExpr()->getValueProvidingExpr();
149152
} else {
150153
break;
151154
}
@@ -710,7 +713,10 @@ class ApplyClassifier {
710713

711714
// If it doesn't have function type, we must have invalid code.
712715
Type argType = fn.getType();
713-
auto argFnType = (argType ? argType->getAs<AnyFunctionType>() : nullptr);
716+
if (!argType) return Classification::forInvalidCode();
717+
718+
auto argFnType =
719+
argType->lookThroughAllOptionalTypes()->getAs<AnyFunctionType>();
714720
if (!argFnType) return Classification::forInvalidCode();
715721

716722
// If it doesn't throw, this argument does not cause the call to throw.

trunk/test/Constraints/sr9102.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
func test(_ a: [Int], _ f: ((Int) -> Bool)?) {
4+
_ = a.filter(f!)
5+
}

0 commit comments

Comments
 (0)