Skip to content

Commit 075dbe2

Browse files
committed
stdlib: Make comparison functions for optional nil transparent
This will generate significantly better code if a generic optional is compared against nil. In a generic function this ended up with a call to the == function. Now, due to mandatory inlining, it boils down to a switch_enum.
1 parent 6cea460 commit 075dbe2

File tree

2 files changed

+42
-0
lines changed

2 files changed

+42
-0
lines changed

stdlib/public/core/Optional.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -345,6 +345,7 @@ public func ~= <T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool {
345345

346346
// Enable equality comparisons against the nil literal, even if the
347347
// element type isn't equatable
348+
@_transparent
348349
public func == <T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool {
349350
switch lhs {
350351
case .some(_):
@@ -354,6 +355,7 @@ public func == <T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool {
354355
}
355356
}
356357

358+
@_transparent
357359
public func != <T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool {
358360
switch lhs {
359361
case .some(_):
@@ -363,6 +365,7 @@ public func != <T>(lhs: T?, rhs: _OptionalNilComparisonType) -> Bool {
363365
}
364366
}
365367

368+
@_transparent
366369
public func == <T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool {
367370
switch rhs {
368371
case .some(_):
@@ -372,6 +375,7 @@ public func == <T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool {
372375
}
373376
}
374377

378+
@_transparent
375379
public func != <T>(lhs: _OptionalNilComparisonType, rhs: T?) -> Bool {
376380
switch rhs {
377381
case .some(_):
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
// RUN: %target-swift-frontend -primary-file %s -emit-sil -o - -verify | FileCheck %s
2+
3+
4+
// CHECK-LABEL: sil {{.*}} @{{.*}}generic_func
5+
// CHECK: switch_enum_addr
6+
// CHECK: return
7+
func generic_func<T>(x: [T]?) -> Bool {
8+
return x == nil
9+
}
10+
11+
// CHECK-LABEL: sil {{.*}} @{{.*}}array_func_rhs_nil
12+
// CHECK: switch_enum_addr
13+
// CHECK: return
14+
func array_func_rhs_nil(x: [Int]?) -> Bool {
15+
return x == nil
16+
}
17+
18+
// CHECK-LABEL: sil {{.*}} @{{.*}}array_func_lhs_nil
19+
// CHECK: switch_enum_addr
20+
// CHECK: return
21+
func array_func_lhs_nil(x: [Int]?) -> Bool {
22+
return nil == x
23+
}
24+
25+
// CHECK-LABEL: sil {{.*}} @{{.*}}array_func_rhs_non_nil
26+
// CHECK: switch_enum_addr
27+
// CHECK: return
28+
func array_func_rhs_non_nil(x: [Int]?) -> Bool {
29+
return x != nil
30+
}
31+
32+
// CHECK-LABEL: sil {{.*}} @{{.*}}array_func_lhs_non_nil
33+
// CHECK: switch_enum_addr
34+
// CHECK: return
35+
func array_func_lhs_non_nil(x: [Int]?) -> Bool {
36+
return nil != x
37+
}
38+

0 commit comments

Comments
 (0)