Skip to content

Commit 7d46760

Browse files
authored
Merge pull request #36614 from slavapestov/reasync-logical-operators
stdlib: Add reasync variants of '&&', '||' and '??'
2 parents df6ad7f + c473869 commit 7d46760

13 files changed

+87
-29
lines changed

stdlib/public/core/Bool.swift

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -276,10 +276,10 @@ extension Bool {
276276
/// - lhs: The left-hand side of the operation.
277277
/// - rhs: The right-hand side of the operation.
278278
@_transparent
279-
@inline(__always)
280-
public static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
279+
@_alwaysEmitIntoClient
280+
public static func && (lhs: Bool, rhs: @autoclosure () async throws -> Bool) reasync rethrows
281281
-> Bool {
282-
return lhs ? try rhs() : false
282+
return lhs ? try await rhs() : false
283283
}
284284

285285
/// Performs a logical OR operation on two Boolean values.
@@ -316,8 +316,24 @@ extension Bool {
316316
/// - lhs: The left-hand side of the operation.
317317
/// - rhs: The right-hand side of the operation.
318318
@_transparent
319-
@inline(__always)
320-
public static func || (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
319+
@_alwaysEmitIntoClient
320+
public static func || (lhs: Bool, rhs: @autoclosure () async throws -> Bool) reasync rethrows
321+
-> Bool {
322+
return lhs ? true : try await rhs()
323+
}
324+
325+
// We keep the old entry points around but mark them unavailable for
326+
// ABI compatibility.
327+
@usableFromInline
328+
@available(*, unavailable)
329+
internal static func && (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
330+
-> Bool {
331+
return lhs ? try rhs() : false
332+
}
333+
334+
@usableFromInline
335+
@available(*, unavailable)
336+
internal static func || (lhs: Bool, rhs: @autoclosure () throws -> Bool) rethrows
321337
-> Bool {
322338
return lhs ? true : try rhs()
323339
}

stdlib/public/core/CMakeLists.txt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,8 @@ endif()
289289
list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concise-pound-file")
290290
list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-ossa-modules")
291291

292+
list(APPEND swift_stdlib_compile_flags "-Xfrontend" "-enable-experimental-concurrency")
293+
292294
if(SWIFT_CHECK_ESSENTIAL_STDLIB)
293295
add_swift_target_library(swift_stdlib_essential ${SWIFT_STDLIB_LIBRARY_BUILD_TYPES} IS_STDLIB IS_STDLIB_CORE
294296
INSTALL_IN_COMPONENT never_install

stdlib/public/core/Optional.swift

Lines changed: 32 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -607,13 +607,14 @@ extension Optional {
607607
/// - defaultValue: A value to use as a default. `defaultValue` is the same
608608
/// type as the `Wrapped` type of `optional`.
609609
@_transparent
610-
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
611-
rethrows -> T {
610+
@_alwaysEmitIntoClient
611+
public func ?? <T>(optional: T?, defaultValue: @autoclosure () async throws -> T)
612+
reasync rethrows -> T {
612613
switch optional {
613614
case .some(let value):
614615
return value
615616
case .none:
616-
return try defaultValue()
617+
return try await defaultValue()
617618
}
618619
}
619620

@@ -660,7 +661,34 @@ public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
660661
/// - defaultValue: A value to use as a default. `defaultValue` and
661662
/// `optional` have the same type.
662663
@_transparent
663-
public func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
664+
@_alwaysEmitIntoClient
665+
public func ?? <T>(optional: T?, defaultValue: @autoclosure () async throws -> T?)
666+
reasync rethrows -> T? {
667+
switch optional {
668+
case .some(let value):
669+
return value
670+
case .none:
671+
return try await defaultValue()
672+
}
673+
}
674+
675+
// We keep the old entry points around but mark them unavailable for
676+
// ABI compatibility.
677+
@usableFromInline
678+
@available(*, unavailable)
679+
internal func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T)
680+
rethrows -> T {
681+
switch optional {
682+
case .some(let value):
683+
return value
684+
case .none:
685+
return try defaultValue()
686+
}
687+
}
688+
689+
@usableFromInline
690+
@available(*, unavailable)
691+
internal func ?? <T>(optional: T?, defaultValue: @autoclosure () throws -> T?)
664692
rethrows -> T? {
665693
switch optional {
666694
case .some(let value):

test/Constraints/implicit_double_cgfloat_conversion.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -103,7 +103,7 @@ func test_various_situations_converting_to_double() {
103103
}
104104

105105
func test_conversions_with_optionals(v: CGFloat?) {
106-
// CHECK: function_ref @$s34implicit_double_cgfloat_conversion31test_conversions_with_optionals1vy12CoreGraphics7CGFloatVSg_tFAFyKXEfu_ : $@convention(thin) () -> (CGFloat, @error Error)
106+
// CHECK: function_ref @$s34implicit_double_cgfloat_conversion31test_conversions_with_optionals1vy12CoreGraphics7CGFloatVSg_tFAFyYKXEfu_ : $@convention(thin) @async () -> (CGFloat, @error Error)
107107
// CHECK: function_ref @$sSd12CoreGraphicsEySdAA7CGFloatVcfC : $@convention(method) (CGFloat, @thin Double.Type) -> Double
108108
let _: Double = (v ?? 0)
109109
}

test/Profiler/coverage_closures.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ func foo() {
1717
// CHECK-LABEL: sil_coverage_map {{.*}}// f1 #1 ((Swift.Int32, Swift.Int32) -> Swift.Bool) -> Swift.Bool in coverage_closures.foo()
1818
// CHECK-NEXT: [[@LINE+1]]:55 -> {{.*}}:4 : 0
1919
func f1(_ closure : (Int32, Int32) -> Bool) -> Bool {
20-
// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () throws -> Swift.Bool in f1
20+
// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () async throws -> Swift.Bool in f1
2121
// CHECK-NEXT: [[@LINE+1]]:29 -> [[@LINE+1]]:42 : 0
2222
return closure(0, 1) && closure(1, 0)
2323
}
@@ -30,7 +30,7 @@ func foo() {
3030

3131
// CHECK-LABEL: sil_coverage_map {{.*}}// closure #3 (Swift.Int32, Swift.Int32) -> Swift.Bool in coverage_closures.foo()
3232
// CHECK-NEXT: [[@LINE+3]]:6 -> [[@LINE+3]]:48 : 0
33-
// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () throws -> {{.*}} in coverage_closures.foo
33+
// CHECK-LABEL: sil_coverage_map {{.*}}// implicit closure #1 () async throws -> {{.*}} in coverage_closures.foo
3434
// CHECK-NEXT: [[@LINE+1]]:36 -> [[@LINE+1]]:46 : 0
3535
f1 { left, right in left == 0 || right == 1 }
3636
}

test/Profiler/instrprof_operators.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ func operators(a : Bool, b : Bool) {
2121
}
2222

2323
// CHECK: implicit closure
24-
// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXEfu_"
24+
// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyYKXEfu_"
2525
// CHECK: %[[HASH:.*]] = integer_literal $Builtin.Int64,
2626
// CHECK: %[[NCOUNTS:.*]] = integer_literal $Builtin.Int32, 1
2727
// CHECK: %[[INDEX:.*]] = integer_literal $Builtin.Int32, 0
2828
// CHECK: builtin "int_instrprof_increment"(%[[NAME]] : {{.*}}, %[[HASH]] : {{.*}}, %[[NCOUNTS]] : {{.*}}, %[[INDEX]] : {{.*}})
2929
// CHECK-NOT: builtin "int_instrprof_increment"
3030

3131
// CHECK: implicit closure
32-
// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyKXEfu0_"
32+
// CHECK: %[[NAME:.*]] = string_literal utf8 "{{.*}}:$s19instrprof_operators0B01a1bySb_SbtFSbyYKXEfu0_"
3333
// CHECK: %[[HASH:.*]] = integer_literal $Builtin.Int64,
3434
// CHECK: %[[NCOUNTS:.*]] = integer_literal $Builtin.Int32, 1
3535
// CHECK: %[[INDEX:.*]] = integer_literal $Builtin.Int32, 0

test/SILGen/capture-transitive.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ func fibonacci(_ n: Int) -> Int {
77
return cache[m] ?? {
88
// Make sure cache is only captured once in the closure
99
// CHECK: implicit closure #1 in recursive #1
10-
// CHECK-LABEL: sil private [transparent] [ossa] @{{.*}}9fibonacci{{.*}}9recursive{{.*}} : $@convention(thin) (Int, @guaranteed { var Dictionary<Int, Int> }) -> (Int, @error Error)
10+
// CHECK-LABEL: sil private [transparent] [ossa] @{{.*}}9fibonacci{{.*}}9recursive{{.*}} : $@convention(thin) @async (Int, @guaranteed { var Dictionary<Int, Int> }) -> (Int, @error Error)
1111
// CHECK: closure #1 in implicit closure #1 in recursive #1
1212
// CHECK-LABEL: sil private [ossa] @{{.*}}9fibonacci{{.*}}9recursive{{.*}} : $@convention(thin) (Int, @guaranteed { var Dictionary<Int, Int> }) -> Int
1313
let output = m < 2 ? m : recursive(m - 1) + recursive(m - 2)

test/SILGen/closures.swift

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -604,15 +604,15 @@ class SuperSub : SuperBase {
604604
func f() {
605605
// CHECK: sil private [ossa] @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> () {
606606
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SuperSub):
607-
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1fyyFyycfU_yyKXEfu_]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
607+
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1fyyFyycfU_yyYKXEfu_]] : $@convention(thin) @async (@guaranteed SuperSub) -> @error Error
608608
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
609609
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
610610
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]]
611611
// CHECK: [[REABSTRACT_PA:%.*]] = partial_apply [callee_guaranteed] {{.*}}([[CVT]])
612612
// CHECK: [[REABSTRACT_CVF:%.*]] = convert_function [[REABSTRACT_PA]]
613613
// CHECK: [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[REABSTRACT_CVF]]
614-
// CHECK: [[TRY_APPLY_AUTOCLOSURE:%.*]] = function_ref @$ss2qqoiyxxSg_xyKXKtKlF :
615-
// CHECK: try_apply [[TRY_APPLY_AUTOCLOSURE]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : {{.*}}, normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
614+
// CHECK: [[TRY_APPLY_AUTOCLOSURE:%.*]] = function_ref @$ss2qqoiyxxSg_xyYKXKtYKlF :
615+
// CHECK: try_apply [noasync] [[TRY_APPLY_AUTOCLOSURE]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : {{.*}}, normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
616616
// CHECK: [[NORMAL_BB]]{{.*}}
617617
// CHECK: } // end sil function '[[INNER_FUNC_1]]'
618618
let f1 = {
@@ -636,19 +636,19 @@ class SuperSub : SuperBase {
636636
func g() {
637637
// CHECK: sil private [ossa] @[[INNER_FUNC_1]] : $@convention(thin) (@guaranteed SuperSub) -> ()
638638
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SuperSub):
639-
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1g.*]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error
639+
// CHECK: [[INNER:%.*]] = function_ref @[[INNER_FUNC_2:\$s8closures8SuperSubC1g.*]] : $@convention(thin) @async (@guaranteed SuperSub) -> @error Error
640640
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
641641
// CHECK: [[PA:%.*]] = partial_apply [callee_guaranteed] [[INNER]]([[ARG_COPY]])
642-
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]] : $@callee_guaranteed () -> @error Error to $@noescape @callee_guaranteed () -> @error Error
643-
// CHECK: [[REABSTRACT_PA:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[CVT]]) : $@convention(thin) (@noescape @callee_guaranteed () -> @error Error) -> (@out (), @error Error)
642+
// CHECK: [[CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[PA]] : $@async @callee_guaranteed () -> @error Error to $@noescape @async @callee_guaranteed () -> @error Error
643+
// CHECK: [[REABSTRACT_PA:%.*]] = partial_apply [callee_guaranteed] {{%.*}}([[CVT]]) : $@convention(thin) @async (@noescape @async @callee_guaranteed () -> @error Error) -> (@out (), @error Error)
644644
// CHECK: [[REABSTRACT_CVF:%.*]] = convert_function [[REABSTRACT_PA]]
645645
// CHECK: [[REABSTRACT_CVT:%.*]] = convert_escape_to_noescape [not_guaranteed] [[REABSTRACT_CVF]]
646-
// CHECK: [[TRY_APPLY_FUNC:%.*]] = function_ref @$ss2qqoiyxxSg_xyKXKtKlF :
647-
// CHECK: try_apply [[TRY_APPLY_FUNC]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : {{.*}}, normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
646+
// CHECK: [[TRY_APPLY_FUNC:%.*]] = function_ref @$ss2qqoiyxxSg_xyYKXKtYKlF :
647+
// CHECK: try_apply [noasync] [[TRY_APPLY_FUNC]]<()>({{.*}}, {{.*}}, [[REABSTRACT_CVT]]) : {{.*}}, normal [[NORMAL_BB:bb1]], error [[ERROR_BB:bb2]]
648648
// CHECK: [[NORMAL_BB]]{{.*}}
649649
// CHECK: } // end sil function '[[INNER_FUNC_1]]'
650650
func g1() {
651-
// CHECK: sil private [transparent] [ossa] @[[INNER_FUNC_2]] : $@convention(thin) (@guaranteed SuperSub) -> @error Error {
651+
// CHECK: sil private [transparent] [ossa] @[[INNER_FUNC_2]] : $@convention(thin) @async (@guaranteed SuperSub) -> @error Error {
652652
// CHECK: bb0([[ARG:%.*]] : @guaranteed $SuperSub):
653653
// CHECK: [[ARG_COPY:%.*]] = copy_value [[ARG]]
654654
// CHECK: [[ARG_COPY_SUPER:%.*]] = upcast [[ARG_COPY]] : $SuperSub to $SuperBase

test/SILGen/dynamic.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -466,13 +466,13 @@ public class Base {
466466
public class Sub : Base {
467467
// CHECK-LABEL: sil hidden [ossa] @$s7dynamic3SubC1xSbvg : $@convention(method) (@guaranteed Sub) -> Bool {
468468
// CHECK: bb0([[SELF:%.*]] : @guaranteed $Sub):
469-
// CHECK: [[AUTOCLOSURE:%.*]] = function_ref @$s7dynamic3SubC1xSbvgSbyKXEfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error)
469+
// CHECK: [[AUTOCLOSURE:%.*]] = function_ref @$s7dynamic3SubC1xSbvgSbyYKXEfu_ : $@convention(thin) @async (@guaranteed Sub) -> (Bool, @error Error)
470470
// CHECK: [[SELF_COPY:%.*]] = copy_value [[SELF]]
471471
// CHECK: = partial_apply [callee_guaranteed] [[AUTOCLOSURE]]([[SELF_COPY]])
472472
// CHECK: return {{%.*}} : $Bool
473473
// CHECK: } // end sil function '$s7dynamic3SubC1xSbvg'
474474

475-
// CHECK-LABEL: sil private [transparent] [ossa] @$s7dynamic3SubC1xSbvgSbyKXEfu_ : $@convention(thin) (@guaranteed Sub) -> (Bool, @error Error) {
475+
// CHECK-LABEL: sil private [transparent] [ossa] @$s7dynamic3SubC1xSbvgSbyYKXEfu_ : $@convention(thin) @async (@guaranteed Sub) -> (Bool, @error Error) {
476476
// CHECK: bb0([[VALUE:%.*]] : @guaranteed $Sub):
477477
// CHECK: [[VALUE_COPY:%.*]] = copy_value [[VALUE]]
478478
// CHECK: [[CAST_VALUE_COPY:%.*]] = upcast [[VALUE_COPY]]
@@ -482,7 +482,7 @@ public class Sub : Base {
482482
// CHECK: = apply [[SUPER]]([[BORROWED_CAST_VALUE_COPY]])
483483
// CHECK: end_borrow [[BORROWED_CAST_VALUE_COPY]]
484484
// CHECK: destroy_value [[CAST_VALUE_COPY]]
485-
// CHECK: } // end sil function '$s7dynamic3SubC1xSbvgSbyKXEfu_'
485+
// CHECK: } // end sil function '$s7dynamic3SubC1xSbvgSbyYKXEfu_'
486486
override var x: Bool { return false || super.x }
487487
}
488488

test/SILGen/mangling.swift

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -88,8 +88,8 @@ func uses_optionals(x: Int?) -> UnicodeScalar? { return nil }
8888
struct HasVarInit {
8989
static var state = true && false
9090
}
91-
// CHECK-LABEL: // function_ref implicit closure #1 () throws -> Swift.Bool in variable initialization expression of static mangling.HasVarInit.state : Swift.Bool
92-
// CHECK-NEXT: function_ref @$s8mangling10HasVarInitV5stateSbvpZfiSbyKXEfu_
91+
// CHECK-LABEL: // function_ref implicit closure #1 () async throws -> Swift.Bool in variable initialization expression of static mangling.HasVarInit.state : Swift.Bool
92+
// CHECK-NEXT: function_ref @$s8mangling10HasVarInitV5stateSbvpZfiSbyYKXEfu_
9393

9494
// auto_closures should not collide with the equivalent non-auto_closure
9595
// function type.

test/api-digester/Outputs/stability-stdlib-source-arm64.swift.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,3 +25,7 @@ Constructor UInt8.init(_:) has parameter 0 type change from Swift.Float80 to Swi
2525
Constructor UInt8.init(exactly:) has parameter 0 type change from Swift.Float80 to Swift.Float16
2626
Struct Float80 has been removed
2727
TypeAlias CLongDouble has underlying type change from Swift.Float80 to Swift.Double
28+
29+
Func Bool.&&(_:_:) is now with @reasync
30+
Func Bool.||(_:_:) is now with @reasync
31+
Func ??(_:_:) is now with @reasync

test/api-digester/Outputs/stability-stdlib-source-x86_64.swift.expected

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,7 @@ Protocol CodingKey has added inherited protocol Sendable
22
Protocol CodingKey has generic signature change from <Self : Swift.CustomDebugStringConvertible, Self : Swift.CustomStringConvertible> to <Self : Swift.CustomDebugStringConvertible, Self : Swift.CustomStringConvertible, Self : Swift.Sendable>
33
Protocol Error has added inherited protocol Sendable
44
Protocol Error has generic signature change from to <Self : Swift.Sendable>
5+
6+
Func Bool.&&(_:_:) is now with @reasync
7+
Func Bool.||(_:_:) is now with @reasync
8+
Func ??(_:_:) is now with @reasync

test/api-digester/stability-stdlib-abi-without-asserts.test

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,3 +57,7 @@ Protocol CodingKey has added inherited protocol Sendable
5757
Protocol CodingKey has generic signature change from <Self : Swift.CustomDebugStringConvertible, Self : Swift.CustomStringConvertible> to <Self : Swift.CustomDebugStringConvertible, Self : Swift.CustomStringConvertible, Self : Swift.Sendable>
5858
Protocol Error has added inherited protocol Sendable
5959
Protocol Error has generic signature change from to <Self : Swift.Sendable>
60+
61+
Func ??(_:_:) has been removed
62+
Func Bool.&&(_:_:) has been removed
63+
Func Bool.||(_:_:) has been removed

0 commit comments

Comments
 (0)