Skip to content

Commit d584153

Browse files
authored
Merge pull request #40078 from hborla/wrong-nil-coalescing-favoring
[CSGen] Don't walk into `??` in `LinkedExprAnalyzer`.
2 parents 0cfc552 + c62e219 commit d584153

File tree

3 files changed

+28
-2
lines changed

3 files changed

+28
-2
lines changed

include/swift/AST/Identifier.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,10 @@ class Identifier {
122122
is(">") || is("<=") || is(">=");
123123
}
124124

125+
bool isNilCoalescingOperator() const {
126+
return is("??");
127+
}
128+
125129
/// isOperatorStartCodePoint - Return true if the specified code point is a
126130
/// valid start of an operator.
127131
static bool isOperatorStartCodePoint(uint32_t C) {

lib/Sema/CSGen.cpp

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -212,7 +212,15 @@ namespace {
212212
return { false, expr };
213213
}
214214

215-
if (isa<BinaryExpr>(expr)) {
215+
if (auto *binaryExpr = dyn_cast<BinaryExpr>(expr)) {
216+
if (auto *overload = dyn_cast<OverloadedDeclRefExpr>(binaryExpr->getFn())) {
217+
// Don't walk into nil coalescing operators. Attempting to favor
218+
// based on operand types is wrong for this operator.
219+
auto identifier = overload->getDecls().front()->getBaseIdentifier();
220+
if (identifier.isNilCoalescingOperator())
221+
return { false, expr };
222+
}
223+
216224
LTI.binaryExprs.push_back(dyn_cast<BinaryExpr>(expr));
217225
}
218226

@@ -367,7 +375,7 @@ namespace {
367375

368376
return true;
369377
}
370-
378+
371379
return false;
372380
}
373381

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %target-swift-frontend -dump-ast %s | %FileCheck %s
2+
3+
struct B {
4+
static var _none: B { B() }
5+
}
6+
7+
struct A {
8+
init(_ other: B) {}
9+
// CHECK: constructor_decl{{.*}}interface type='(A.Type) -> (B?) -> A'
10+
init(_ other: B?) {
11+
// CHECK: dot_syntax_call_expr type='(B) -> A'
12+
self.init(other ?? ._none)
13+
}
14+
}

0 commit comments

Comments
 (0)