Skip to content

Commit 87e3e3d

Browse files
committed
[CSBindings] Don't delay inferred loeading-dot base inference if source is a contextual type
Transitively inferring a protocol type binding from a contextual type means that the binding set for a leading-dot member reference is complete because there could be no other sources of bindings when expression is connected directly to a contextual type. Resolves: rdar://145103149
1 parent 80050bb commit 87e3e3d

File tree

2 files changed

+39
-3
lines changed

2 files changed

+39
-3
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -129,9 +129,15 @@ bool BindingSet::isDelayed() const {
129129
if (Bindings.empty())
130130
return true;
131131

132-
133-
if (Bindings[0].BindingType->is<ProtocolType>())
134-
return true;
132+
if (Bindings[0].BindingType->is<ProtocolType>()) {
133+
auto *locator = Bindings[0].getLocator();
134+
// If the binding got inferred from a contextual type
135+
// this set shouldn't be delayed because there won't
136+
// be any other inference sources for this leading-dot
137+
// syntax member.
138+
if (!locator->findLast<LocatorPathElt::ContextualType>())
139+
return true;
140+
}
135141
}
136142

137143
// Since force unwrap preserves l-valueness, resulting

test/Constraints/result_builder.swift

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1402,3 +1402,33 @@ func testBuildFinalResultDependentOnContextualType() {
14021402

14031403
testBuildFinalResultDependentOnContextualType()
14041404
// CHECK: Optional(42)
1405+
1406+
protocol TestLeadingDot {
1407+
}
1408+
1409+
@resultBuilder
1410+
struct IntBuilder {
1411+
static func buildBlock(_ v: Int) -> Int {
1412+
print("buildBlock: \(v)")
1413+
return v
1414+
}
1415+
}
1416+
1417+
extension TestLeadingDot where Self == NoopImpl {
1418+
static func test(@IntBuilder builder: () -> Int) -> NoopImpl {
1419+
builder()
1420+
return NoopImpl()
1421+
}
1422+
}
1423+
1424+
struct NoopImpl : TestLeadingDot {
1425+
}
1426+
1427+
func testLeadingDotSyntax(v: Int) {
1428+
let x: some TestLeadingDot = .test {
1429+
v
1430+
}
1431+
}
1432+
1433+
testLeadingDotSyntax(v: -42)
1434+
// CHECK: buildBlock: -42

0 commit comments

Comments
 (0)