Skip to content

Commit 50a76c8

Browse files
committed
[CSBindings] New binding formed by join operation should refer to constraint that triggered join
Using existing binding with updated type would result in incorrect behavior in incremental mode since when "originating" (new) constraint gets retracted it would leave a stale binding behind.
1 parent 578adca commit 50a76c8

File tree

2 files changed

+15
-1
lines changed

2 files changed

+15
-1
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -597,7 +597,10 @@ bool PotentialBindings::addPotentialBinding(PotentialBinding binding,
597597
Type::join(existingBinding->BindingType, binding.BindingType);
598598

599599
if (join && isAcceptableJoin(*join)) {
600-
joined.push_back(existingBinding->withType(*join));
600+
// Result of the join has to use new binding because it refers
601+
// to the constraint that triggered the join that replaced the
602+
// existing binding.
603+
joined.push_back(binding.withType(*join));
601604
// Remove existing binding from the set.
602605
// It has to be re-introduced later, since its type has been changed.
603606
existingBinding = Bindings.erase(existingBinding);

test/Sema/type_join.swift

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -120,3 +120,14 @@ func rdar37241221(_ a: C?, _ b: D?) {
120120
let inferred = [a!, b]
121121
expectEqualType(type(of: array_c_opt).self, type(of: inferred).self)
122122
}
123+
124+
extension FixedWidthInteger {
125+
public static func test_nonstale_join_result<Other: BinaryInteger>(_ lhs: inout Self, _ rhs: Other) {
126+
let shift = rhs < -Self.bitWidth ? -Self.bitWidth
127+
: rhs > Self.bitWidth ? Self.bitWidth
128+
: Int(rhs) // `shift` is `Int`
129+
130+
func accepts_int(_: Int) {}
131+
accepts_int(shift) // Ok
132+
}
133+
}

0 commit comments

Comments
 (0)