@@ -352,13 +352,17 @@ extension DatabasePool: DatabaseReader {
352352 }
353353
354354 public func read< T: Sendable > (
355- _ value: @escaping @ Sendable ( Database) throws -> T
355+ _ value: sending @escaping ( Database ) throws -> T
356356 ) async throws -> T {
357357 GRDBPrecondition ( currentReader == nil , " Database methods are not reentrant. " )
358358 guard let readerPool else {
359359 throw DatabaseError . connectionIsClosed ( )
360360 }
361361
362+ // Avoid compiler warning. There is no data race because `value` is invoked once.
363+ typealias SendableClosure = @Sendable ( Database) throws -> T
364+ let value = unsafeBitCast ( value, to: SendableClosure . self)
365+
362366 let dbAccess = CancellableDatabaseAccess ( )
363367 return try await dbAccess. withCancellableContinuation { continuation in
364368 readerPool. asyncGet { result in
@@ -390,13 +394,17 @@ extension DatabasePool: DatabaseReader {
390394 }
391395
392396 public func asyncRead(
393- _ value: @escaping @ Sendable ( Result < Database , Error > ) -> Void
397+ _ value: sending @escaping ( Result < Database , Error > ) -> Void
394398 ) {
395399 guard let readerPool else {
396400 value ( . failure( DatabaseError . connectionIsClosed ( ) ) )
397401 return
398402 }
399403
404+ // Avoid compiler warning. There is no data race because `value` is invoked once.
405+ typealias SendableClosure = @Sendable ( Result < Database , Error > ) -> Void
406+ let value = unsafeBitCast ( value, to: SendableClosure . self)
407+
400408 readerPool. asyncGet { result in
401409 do {
402410 let ( reader, releaseReader) = try result. get ( )
@@ -436,12 +444,16 @@ extension DatabasePool: DatabaseReader {
436444 }
437445
438446 public func unsafeRead< T: Sendable > (
439- _ value: @escaping @ Sendable ( Database) throws -> T
447+ _ value: sending @escaping ( Database ) throws -> T
440448 ) async throws -> T {
441449 guard let readerPool else {
442450 throw DatabaseError . connectionIsClosed ( )
443451 }
444452
453+ // Avoid compiler warning. There is no data race because `value` is invoked once.
454+ typealias SendableClosure = @Sendable ( Database) throws -> T
455+ let value = unsafeBitCast ( value, to: SendableClosure . self)
456+
445457 let dbAccess = CancellableDatabaseAccess ( )
446458 return try await dbAccess. withCancellableContinuation { continuation in
447459 readerPool. asyncGet { result in
@@ -470,13 +482,17 @@ extension DatabasePool: DatabaseReader {
470482 }
471483
472484 public func asyncUnsafeRead(
473- _ value: @escaping @ Sendable ( Result < Database , Error > ) -> Void
485+ _ value: sending @escaping ( Result < Database , Error > ) -> Void
474486 ) {
475487 guard let readerPool else {
476488 value ( . failure( DatabaseError . connectionIsClosed ( ) ) )
477489 return
478490 }
479491
492+ // Avoid compiler warning. There is no data race because `value` is invoked once.
493+ typealias SendableClosure = @Sendable ( Result < Database , Error > ) -> Void
494+ let value = unsafeBitCast ( value, to: SendableClosure . self)
495+
480496 readerPool. asyncGet { result in
481497 do {
482498 let ( reader, releaseReader) = try result. get ( )
@@ -517,7 +533,7 @@ extension DatabasePool: DatabaseReader {
517533 }
518534
519535 public func spawnConcurrentRead(
520- _ value: @escaping @ Sendable ( Result < Database , Error > ) -> Void
536+ _ value: sending @escaping ( Result < Database , Error > ) -> Void
521537 ) {
522538 asyncConcurrentRead ( value)
523539 }
@@ -560,7 +576,7 @@ extension DatabasePool: DatabaseReader {
560576 ///
561577 /// - parameter value: A function that accesses the database.
562578 public func asyncConcurrentRead(
563- _ value: @escaping @ Sendable ( Result < Database , Error > ) -> Void
579+ _ value: sending @escaping ( Result < Database , Error > ) -> Void
564580 ) {
565581 // Check that we're on the writer queue...
566582 writer. execute { db in
@@ -802,7 +818,7 @@ extension DatabasePool: DatabaseWriter {
802818 }
803819
804820 public func writeWithoutTransaction< T: Sendable > (
805- _ updates: @escaping @ Sendable ( Database) throws -> T
821+ _ updates: sending @escaping ( Database ) throws -> T
806822 ) async throws -> T {
807823 try await writer. execute ( updates)
808824 }
@@ -818,8 +834,12 @@ extension DatabasePool: DatabaseWriter {
818834 }
819835
820836 public func barrierWriteWithoutTransaction< T: Sendable > (
821- _ updates: @escaping @ Sendable ( Database) throws -> T
837+ _ updates: sending @escaping ( Database ) throws -> T
822838 ) async throws -> T {
839+ // Avoid compiler warning. There is no data race because `updates` is invoked once.
840+ typealias SendableClosure = @Sendable ( Database) throws -> T
841+ let updates = unsafeBitCast ( updates, to: SendableClosure . self)
842+
823843 let dbAccess = CancellableDatabaseAccess ( )
824844 return try await dbAccess. withCancellableContinuation { continuation in
825845 asyncBarrierWriteWithoutTransaction { dbResult in
@@ -838,7 +858,7 @@ extension DatabasePool: DatabaseWriter {
838858 }
839859
840860 public func asyncBarrierWriteWithoutTransaction(
841- _ updates: @escaping @ Sendable ( Result < Database , Error > ) -> Void
861+ _ updates: sending @escaping ( Result < Database , Error > ) -> Void
842862 ) {
843863 guard let readerPool else {
844864 updates ( . failure( DatabaseError . connectionIsClosed ( ) ) )
@@ -894,7 +914,7 @@ extension DatabasePool: DatabaseWriter {
894914 }
895915
896916 public func asyncWriteWithoutTransaction(
897- _ updates: @escaping @ Sendable ( Database ) -> Void
917+ _ updates: sending @escaping ( Database ) -> Void
898918 ) {
899919 writer. async ( updates)
900920 }
0 commit comments