Skip to content

Commit a2d971e

Browse files
committed
Sema: Don't attempt deep equality if we're also attempting optional-to-optional
1 parent eeb4a5e commit a2d971e

File tree

3 files changed

+55
-3
lines changed

3 files changed

+55
-3
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 33 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8100,6 +8100,38 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
81008100
if (conversionsOrFixes.empty())
81018101
return getTypeMatchFailure(locator);
81028102

8103+
std::optional<ConversionRestrictionKind> redundantDeepEquality;
8104+
bool sawDeepEquality = false;
8105+
8106+
for (auto potential : conversionsOrFixes) {
8107+
if (auto restriction = potential.getRestriction()) {
8108+
switch (*restriction) {
8109+
case ConversionRestrictionKind::DeepEquality:
8110+
sawDeepEquality = true;
8111+
break;
8112+
case ConversionRestrictionKind::OptionalToOptional:
8113+
redundantDeepEquality = *restriction;
8114+
break;
8115+
default:
8116+
break;
8117+
}
8118+
}
8119+
}
8120+
8121+
auto favoredRestriction = ConversionRestrictionKind::DeepEquality;
8122+
if (sawDeepEquality && redundantDeepEquality) {
8123+
favoredRestriction = *redundantDeepEquality;
8124+
8125+
conversionsOrFixes.erase(
8126+
llvm::remove_if(conversionsOrFixes,
8127+
[&](RestrictionOrFix &potential) {
8128+
if (auto restriction = potential.getRestriction())
8129+
return *restriction == ConversionRestrictionKind::DeepEquality;
8130+
return false;
8131+
}),
8132+
conversionsOrFixes.end());
8133+
}
8134+
81038135
// Where there is more than one potential conversion, create a disjunction
81048136
// so that we'll explore all of the options.
81058137
if (conversionsOrFixes.size() > 1) {
@@ -8119,7 +8151,7 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
81198151
Constraint::createRestricted(*this, constraintKind, *restriction,
81208152
type1, type2, fixedLocator));
81218153

8122-
if (constraints.back()->getKind() == ConstraintKind::Bind)
8154+
if (*restriction == favoredRestriction)
81238155
constraints.back()->setFavored();
81248156

81258157
continue;
@@ -14482,8 +14514,6 @@ ConstraintSystem::simplifyRestrictedConstraintImpl(
1448214514
// also:
1448314515
// T <c U ===> T? <c U!
1448414516
case ConversionRestrictionKind::OptionalToOptional: {
14485-
addContextualScore();
14486-
1448714517
assert(matchKind >= ConstraintKind::Subtype);
1448814518
if (auto generic1 = type1->getAs<BoundGenericType>()) {
1448914519
if (auto generic2 = type2->getAs<BoundGenericType>()) {

test/Constraints/closures.swift

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1305,3 +1305,13 @@ do {
13051305
})
13061306
}
13071307
}
1308+
1309+
func rdar143338891() {
1310+
func takesAny(_: Any?) {}
1311+
1312+
class Test {
1313+
func test() {
1314+
_ = { [weak self] in takesAny(self) }
1315+
}
1316+
}
1317+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// RUN: %target-typecheck-verify-swift -solver-scope-threshold=40000
2+
3+
func f(str1: String, str2: String) -> (Any.Type)? {
4+
return _typeByName(str1)
5+
?? _typeByName(str2)
6+
?? _typeByName("a.\(str2)")
7+
?? _typeByName("b.\(str2)")
8+
?? _typeByName("c.\(str2)")
9+
?? _typeByName("d.\(str2)")
10+
?? _typeByName("e.\(str2)")
11+
?? _typeByName("f.\(str2)")
12+
}

0 commit comments

Comments
 (0)