Skip to content

Commit

Permalink
Allow non-Sendable construction of UnxipStream.xip
Browse files Browse the repository at this point in the history
DataReader (and potentially some of the bare sequences that people would
want to use here) are intentionally not Sendable. Unxip.makeStream
consumes them, but the UnxipStream.xip factory method takes them to set
up generic parameters correctly. This conflicts with Sendable checking
because the compiler thinks that the first call could stash away a
reference, preventing it from being sent into unxip's isolation domain.
However, these methods don't actually *do* anything with the parameter:
we solely use it for its type. Serendipitously taking the parameter as
@autoclosure (which we have no need to evaluate) is enough to satisfy
the compiler that we have no interest in the parameter's value.

Also, clean up some code I split up earlier and accidentally committed.
  • Loading branch information
saagarjha committed Oct 1, 2024
1 parent d6f0009 commit 61e876e
Showing 1 changed file with 3 additions and 4 deletions.
7 changes: 3 additions & 4 deletions unxip.swift
Original file line number Diff line number Diff line change
Expand Up @@ -1319,11 +1319,11 @@ public enum Disk: StreamAperture {
}

public struct UnxipStream<T: StreamAperture> {
public static func xip<S: AsyncSequence>(wrapping: S) -> UnxipStream<XIP<S>> where S.Element: RandomAccessCollection, S.Element.Element == UInt8 {
public static func xip<S: AsyncSequence>(wrapping: @autoclosure () -> S) -> UnxipStream<XIP<S>> where S.Element: RandomAccessCollection, S.Element.Element == UInt8 {
return .init()
}

public static func xip<S: AsyncSequence>(input: DataReader<S>) -> UnxipStream<XIP<S>> where S.Element: RandomAccessCollection, S.Element.Element == UInt8 {
public static func xip<S: AsyncSequence>(input: @autoclosure () -> DataReader<S>) -> UnxipStream<XIP<S>> where S.Element: RandomAccessCollection, S.Element.Element == UInt8 {
return .init()
}

Expand All @@ -1346,8 +1346,7 @@ public struct Unxip {
}

public static func makeStream<Start: StreamAperture, End: StreamAperture>(from start: UnxipStream<Start>, to end: UnxipStream<End>, input: sending Start.Input, _ option1: Start.Options? = nil, _ option2: Start.Next.Options? = nil) -> End.Input where Start.Next.Next == End {
let input = Start.transform(input, options: option1)
return Start.Next.transform(input, options: option2)
return Start.Next.transform(Start.transform(input, options: option1), options: option2)
}

public static func makeStream<Start: StreamAperture, End: StreamAperture>(from start: UnxipStream<Start>, to end: UnxipStream<End>, input: sending Start.Input, _ option1: Start.Options? = nil) -> End.Input where Start.Next == End {
Expand Down

0 comments on commit 61e876e

Please sign in to comment.