Skip to content

Commit c40fd39

Browse files
committed
[ConstraintSystem] Remove an unsound optimization hack for generic functions.
I think there is something far more narrow we could do here, but I'm not sure if there is real code that such a hack would benefit from. We can leave that to consider another day. Fixes rdar://problem/40819547 (aka https://bugs.swift.org/browse/SR-7884).
1 parent e8ee93b commit c40fd39

File tree

5 files changed

+22
-63
lines changed

5 files changed

+22
-63
lines changed

lib/Sema/ConstraintSystem.cpp

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@
22
//
33
// This source file is part of the Swift.org open source project
44
//
5-
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
5+
// Copyright (c) 2014 - 2018 Apple Inc. and the Swift project authors
66
// Licensed under Apache License v2.0 with Runtime Library Exception
77
//
88
// See https://swift.org/LICENSE.txt for license information
@@ -1448,64 +1448,6 @@ ConstraintSystem::getTypeOfMemberReference(
14481448
return { openedType, type };
14491449
}
14501450

1451-
// Performance hack: if there are two generic overloads, and one is
1452-
// more specialized than the other, prefer the more-specialized one.
1453-
static void tryOptimizeGenericDisjunction(ConstraintSystem &cs,
1454-
ArrayRef<OverloadChoice> choices,
1455-
OverloadChoice *&favoredChoice) {
1456-
if (favoredChoice || choices.size() != 2)
1457-
return;
1458-
1459-
const auto &choiceA = choices[0];
1460-
const auto &choiceB = choices[1];
1461-
1462-
if (!choiceA.isDecl() || !choiceB.isDecl())
1463-
return;
1464-
1465-
auto isViable = [](ValueDecl *decl) -> bool {
1466-
assert(decl);
1467-
1468-
auto *AFD = dyn_cast<AbstractFunctionDecl>(decl);
1469-
if (!AFD || !AFD->isGeneric())
1470-
return false;
1471-
1472-
auto funcType = AFD->getInterfaceType();
1473-
auto hasAny = funcType.findIf([](Type type) -> bool {
1474-
if (auto objType = type->getOptionalObjectType())
1475-
return objType->isAny();
1476-
1477-
return type->isAny();
1478-
});
1479-
1480-
// If function declaration references `Any` or `Any?` type
1481-
// let's not attempt it, because it's unclear
1482-
// without solving which overload is going to be better.
1483-
return !hasAny;
1484-
};
1485-
1486-
auto *declA = choiceA.getDecl();
1487-
auto *declB = choiceB.getDecl();
1488-
1489-
if (!isViable(declA) || !isViable(declB))
1490-
return;
1491-
1492-
auto &TC = cs.TC;
1493-
auto *DC = cs.DC;
1494-
1495-
switch (TC.compareDeclarations(DC, declA, declB)) {
1496-
case Comparison::Better:
1497-
favoredChoice = const_cast<OverloadChoice *>(&choiceA);
1498-
break;
1499-
1500-
case Comparison::Worse:
1501-
favoredChoice = const_cast<OverloadChoice *>(&choiceB);
1502-
break;
1503-
1504-
case Comparison::Unordered:
1505-
break;
1506-
}
1507-
}
1508-
15091451
void ConstraintSystem::addOverloadSet(Type boundType,
15101452
ArrayRef<OverloadChoice> choices,
15111453
DeclContext *useDC,
@@ -1520,8 +1462,6 @@ void ConstraintSystem::addOverloadSet(Type boundType,
15201462
return;
15211463
}
15221464

1523-
tryOptimizeGenericDisjunction(*this, choices, favoredChoice);
1524-
15251465
SmallVector<Constraint *, 4> overloads;
15261466

15271467
// As we do for other favored constraints, if a favored overload has been

test/Constraints/optional.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ func test9(_ i: Int, io: Int?) {
9494
let _: Double = result2
9595

9696
let result3 = test9_helper2(i)
97-
var _: Double = result3
97+
var _: Int = result3
9898
let result4 = test9_helper2(io)
9999
let _: Double = result4
100100
}

test/Constraints/sr7884.swift

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// SR-7884
4+
func f<T>(_ x: T) -> T {
5+
return x
6+
}
7+
8+
func f<T>(_ x: T?) -> T? {
9+
return x
10+
}
11+
12+
let r = f(1) // calls optional variant
13+
let _ = r! // expected-error {{cannot force unwrap value of non-optional type 'Int'}}
14+
15+
// SR-7899
16+
let optSeq: LazySequence<[Int]>? = nil
17+
let lazySequence = optSeq?.lazy
18+
let value = lazySequence?.compactMap({ $0 as? Int }).first // expected-warning {{conditional cast from 'Int' to 'Int' always succeeds}}
19+
let _: Int = value!

validation-test/Sema/type_checker_perf/fast/more_specialized_generic_func.swift.gyb renamed to validation-test/Sema/type_checker_perf/slow/more_specialized_generic_func.swift.gyb

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// RUN: %scale-test --begin 1 --end 10 --step 1 --select incrementScopeCounter %s --expected-exit-code 0
1+
// RUN: %scale-test --invert-result --begin 1 --end 10 --step 1 --select incrementScopeCounter %s --expected-exit-code 0
22
// REQUIRES: OS=macosx
33
// REQUIRES: asserts
44

0 commit comments

Comments
 (0)