Skip to content

Commit d66f233

Browse files
Add concrete overload for != on all stdlib integer types. (swiftlang#70043)
* Add concrete overload for on all stdlib integer types. * Add very basic tests for type inference of comparands. * Add a comment explaining why these overloads are present.
1 parent 013e671 commit d66f233

File tree

2 files changed

+43
-0
lines changed

2 files changed

+43
-0
lines changed

stdlib/public/core/IntegerTypes.swift.gyb

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1715,6 +1715,32 @@ ${operatorComment(x.operator, True)}
17151715

17161716
% end
17171717

1718+
// IMPORTANT: The following four apparently unnecessary overloads of
1719+
// comparison operations are necessary for literal comparands to be
1720+
// inferred as the desired type.
1721+
//
1722+
// Absent these, an expression like `Int8.min != 1 << 7` would have
1723+
// two candidates for `!=`: the heterogeneous generic operator defined
1724+
// on BinaryInteger, and the homogeneous generic operator defined on
1725+
// Equatable. The heterogeneous one is chosen because it is "more
1726+
// specialized," which results in `1 << 7` being given the type `Int`
1727+
// and the value 128, which compares not-equal to `Int8.min`.
1728+
//
1729+
// However, there is necessarily a homogeneous concrete `==` operator
1730+
// because it is a customization point for Equatable, so the expression
1731+
// `Int8.min == 1 << 7` types `1 << 7` as `Int8` with value -128, which
1732+
// compares equal to `Int8.min`.
1733+
//
1734+
// This inconsistency can be resolved by ensuring that we have
1735+
// concrete overloads of every comparison operation. It's still possible
1736+
// to get literal expression comparands typed Int in generic contexts,
1737+
// but there's also a pretty straightforward workaround (adding an
1738+
// explicit type).
1739+
@_transparent @_alwaysEmitIntoClient
1740+
public static func !=(lhs: ${Self}, rhs: ${Self}) -> Bool {
1741+
return !(lhs == rhs)
1742+
}
1743+
17181744
@_transparent
17191745
public static func <= (lhs: ${Self}, rhs: ${Self}) -> Bool {
17201746
return !(rhs < lhs)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
// RUN: %target-run-simple-swift
2+
// REQUIRES: executable_test
3+
4+
import StdlibUnittest
5+
6+
let ComparisonTypeInferenceTests = TestSuite("Comparison type inference")
7+
8+
ComparisonTypeInferenceTests.test("Int8") {
9+
expectTrue( Int8.min == 1 << 7)
10+
expectFalse(Int8.min != 1 << 7)
11+
expectTrue( Int8.max > 1 << 7)
12+
expectTrue( Int8.max >= 1 << 7)
13+
expectTrue( 1 << 7 < Int8.max)
14+
expectTrue( 1 << 7 <= Int8.max)
15+
}
16+
17+
runAllTests()

0 commit comments

Comments
 (0)