From f85a7dab03e7446df99aaca91317dc2cb11c3e98 Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 6 May 2022 11:26:43 +0100 Subject: [PATCH 1/7] Make RawStructuredFieldValues sendable --- .../ComponentTypes.swift | 10 +++++----- Sources/RawStructuredFieldValues/Errors.swift | 2 +- .../FieldParser.swift | 4 ++++ .../FieldSerializer.swift | 2 +- .../RawStructuredFieldValues/OrderedMap.swift | 4 ++-- .../PseudoDecimal.swift | 2 +- .../RawStructuredFieldValues/Sendable.swift | 19 +++++++++++++++++++ .../Decoder/StructuredFieldValueDecoder.swift | 4 ++-- 8 files changed, 35 insertions(+), 12 deletions(-) create mode 100644 Sources/RawStructuredFieldValues/Sendable.swift diff --git a/Sources/RawStructuredFieldValues/ComponentTypes.swift b/Sources/RawStructuredFieldValues/ComponentTypes.swift index 4aabab8..6e9dc69 100644 --- a/Sources/RawStructuredFieldValues/ComponentTypes.swift +++ b/Sources/RawStructuredFieldValues/ComponentTypes.swift @@ -21,7 +21,7 @@ /// `ItemOrInnerList` represents the values in a structured header dictionary, or the /// entries in a structured header list. -public enum ItemOrInnerList { +public enum ItemOrInnerList: _Sendable { case item(Item) case innerList(InnerList) } @@ -32,7 +32,7 @@ extension ItemOrInnerList: Hashable {} /// `BareItem` is a representation of the base data types at the bottom of a structured /// header field. These types are not parameterised: they are raw data. -public enum BareItem { +public enum BareItem: _Sendable { /// A boolean item. case bool(Bool) @@ -87,7 +87,7 @@ extension BareItem: Hashable {} /// `Item` represents a structured header field item: a combination of a `bareItem` /// and some parameters. -public struct Item { +public struct Item: _Sendable { /// The `BareItem` that this `Item` contains. public var bareItem: BareItem @@ -106,7 +106,7 @@ extension Item: Hashable {} /// A `BareInnerList` represents the items contained within an `InnerList`, without /// the associated parameters. -public struct BareInnerList: Hashable { +public struct BareInnerList: Hashable, _Sendable { private var items: [Item] public init() { @@ -179,7 +179,7 @@ extension BareInnerList.Index: Comparable { // MARK: - InnerList /// An `InnerList` is a list of items, with some associated parameters. -public struct InnerList: Hashable { +public struct InnerList: Hashable, _Sendable { /// The items contained within this inner list. public var bareInnerList: BareInnerList diff --git a/Sources/RawStructuredFieldValues/Errors.swift b/Sources/RawStructuredFieldValues/Errors.swift index d18950a..825d4ff 100644 --- a/Sources/RawStructuredFieldValues/Errors.swift +++ b/Sources/RawStructuredFieldValues/Errors.swift @@ -15,7 +15,7 @@ // MARK: - StructuredHeaderError /// Errors that may be encountered when working with structured headers. -public struct StructuredHeaderError: Error { +public struct StructuredHeaderError: Error, _Sendable { private enum _BaseError: Hashable { case invalidTrailingBytes case invalidInnerList diff --git a/Sources/RawStructuredFieldValues/FieldParser.swift b/Sources/RawStructuredFieldValues/FieldParser.swift index c509c7f..986e9bf 100644 --- a/Sources/RawStructuredFieldValues/FieldParser.swift +++ b/Sources/RawStructuredFieldValues/FieldParser.swift @@ -25,6 +25,10 @@ public struct StructuredFieldValueParser where } } +extension StructuredFieldValueParser: _Sendable where BaseData: _Sendable, BaseData.SubSequence: _Sendable { + +} + extension StructuredFieldValueParser { // Helper typealiases to avoid the explosion of generic parameters public typealias BareItem = RawStructuredFieldValues.BareItem diff --git a/Sources/RawStructuredFieldValues/FieldSerializer.swift b/Sources/RawStructuredFieldValues/FieldSerializer.swift index 60beb17..c02d6e2 100644 --- a/Sources/RawStructuredFieldValues/FieldSerializer.swift +++ b/Sources/RawStructuredFieldValues/FieldSerializer.swift @@ -15,7 +15,7 @@ private let validIntegerRange = Int64(-999_999_999_999_999) ... Int64(999_999_999_999_999) /// A `StructuredFieldValueSerializer` is the basic parsing object for structured header field values. -public struct StructuredFieldValueSerializer { +public struct StructuredFieldValueSerializer: _Sendable { private var data: [UInt8] public init() { diff --git a/Sources/RawStructuredFieldValues/OrderedMap.swift b/Sources/RawStructuredFieldValues/OrderedMap.swift index baad07f..580a0cb 100644 --- a/Sources/RawStructuredFieldValues/OrderedMap.swift +++ b/Sources/RawStructuredFieldValues/OrderedMap.swift @@ -23,7 +23,7 @@ /// Note that this preserves _original_ insertion order: if you overwrite a key's value, the /// key does not move to "last". This is a specific requirement for Structured Headers and may /// harm the generality of this implementation. -public struct OrderedMap where Key: Hashable { +public struct OrderedMap: _Sendable where Key: Hashable { private var backing: [Entry] public init() { @@ -70,7 +70,7 @@ extension OrderedMap { // MARK: - Collection conformances extension OrderedMap: RandomAccessCollection, MutableCollection { - public struct Index { + public struct Index: _Sendable { fileprivate var baseIndex: Array<(Key, Value)>.Index fileprivate init(_ baseIndex: Array<(Key, Value)>.Index) { diff --git a/Sources/RawStructuredFieldValues/PseudoDecimal.swift b/Sources/RawStructuredFieldValues/PseudoDecimal.swift index 87e7bd5..38d6feb 100644 --- a/Sources/RawStructuredFieldValues/PseudoDecimal.swift +++ b/Sources/RawStructuredFieldValues/PseudoDecimal.swift @@ -34,7 +34,7 @@ import Glibc /// is 999,999,999,999,999. The exponent ranges from -3 to 0. Additionally, there may be no more than 12 decimal digits before /// the decimal place, so while the maximum value of the significand is 999,999,999,999,999, that is only acceptable if the /// exponent is -3. -public struct PseudoDecimal: Hashable { +public struct PseudoDecimal: Hashable, _Sendable { private var _mantissa: Int64 private var _exponent: Int8 diff --git a/Sources/RawStructuredFieldValues/Sendable.swift b/Sources/RawStructuredFieldValues/Sendable.swift new file mode 100644 index 0000000..fd6fe58 --- /dev/null +++ b/Sources/RawStructuredFieldValues/Sendable.swift @@ -0,0 +1,19 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the SwiftNIO open source project +// +// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Licensed under Apache License v2.0 +// +// See LICENSE.txt for license information +// See CONTRIBUTORS.txt for the list of SwiftNIO project authors +// +// SPDX-License-Identifier: Apache-2.0 +// +//===----------------------------------------------------------------------===// + +#if swift(>=5.5) && canImport(_Concurrency) +public typealias _Sendable = Sendable +#else +public typealias _Sendable = Any +#endif diff --git a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift index ed50b96..e14f604 100644 --- a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift @@ -16,7 +16,7 @@ import RawStructuredFieldValues /// A `StructuredFieldValueDecoder` allows decoding `Decodable` objects from a HTTP /// structured header field. -public struct StructuredFieldValueDecoder { +public struct StructuredFieldValueDecoder: _Sendable { /// A strategy that should be used to map coding keys to wire format keys. public var keyDecodingStrategy: KeyDecodingStrategy? @@ -25,7 +25,7 @@ public struct StructuredFieldValueDecoder { extension StructuredFieldValueDecoder { /// A strategy that should be used to map coding keys to wire format keys. - public struct KeyDecodingStrategy: Hashable { + public struct KeyDecodingStrategy: Hashable, _Sendable { fileprivate enum Base: Hashable { case lowercase } From acc4e850179780c93709c8fb3c0af6c0d2656c2b Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 6 May 2022 11:28:06 +0100 Subject: [PATCH 2/7] Make StructuredFieldValues Sendable --- .../Encoder/StructuredFieldValueEncoder.swift | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift index 9474f6c..e6c1371 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift @@ -16,7 +16,7 @@ import RawStructuredFieldValues /// A `StructuredFieldValueEncoder` allows encoding `Encodable` objects to the format of a HTTP /// structured header field. -public struct StructuredFieldValueEncoder { +public struct StructuredFieldValueEncoder: _Sendable { public var keyEncodingStrategy: KeyEncodingStrategy? public init() {} @@ -24,7 +24,7 @@ public struct StructuredFieldValueEncoder { extension StructuredFieldValueEncoder { /// A strategy that should be used to map coding keys to wire format keys. - public struct KeyEncodingStrategy: Hashable { + public struct KeyEncodingStrategy: Hashable, _Sendable { fileprivate enum Base: Hashable { case lowercase } From f696b93efb53781e34ff201a95e49274faaf10bb Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 6 May 2022 14:10:40 +0100 Subject: [PATCH 3/7] Rename _Sendable to SHSendable --- Sources/RawStructuredFieldValues/ComponentTypes.swift | 10 +++++----- Sources/RawStructuredFieldValues/Errors.swift | 2 +- Sources/RawStructuredFieldValues/FieldParser.swift | 2 +- Sources/RawStructuredFieldValues/FieldSerializer.swift | 2 +- Sources/RawStructuredFieldValues/OrderedMap.swift | 4 ++-- Sources/RawStructuredFieldValues/PseudoDecimal.swift | 2 +- Sources/RawStructuredFieldValues/Sendable.swift | 4 ++-- .../Decoder/StructuredFieldValueDecoder.swift | 4 ++-- .../Encoder/StructuredFieldValueEncoder.swift | 4 ++-- 9 files changed, 17 insertions(+), 17 deletions(-) diff --git a/Sources/RawStructuredFieldValues/ComponentTypes.swift b/Sources/RawStructuredFieldValues/ComponentTypes.swift index 6e9dc69..9dd0001 100644 --- a/Sources/RawStructuredFieldValues/ComponentTypes.swift +++ b/Sources/RawStructuredFieldValues/ComponentTypes.swift @@ -21,7 +21,7 @@ /// `ItemOrInnerList` represents the values in a structured header dictionary, or the /// entries in a structured header list. -public enum ItemOrInnerList: _Sendable { +public enum ItemOrInnerList: SHSendable { case item(Item) case innerList(InnerList) } @@ -32,7 +32,7 @@ extension ItemOrInnerList: Hashable {} /// `BareItem` is a representation of the base data types at the bottom of a structured /// header field. These types are not parameterised: they are raw data. -public enum BareItem: _Sendable { +public enum BareItem: SHSendable { /// A boolean item. case bool(Bool) @@ -87,7 +87,7 @@ extension BareItem: Hashable {} /// `Item` represents a structured header field item: a combination of a `bareItem` /// and some parameters. -public struct Item: _Sendable { +public struct Item: SHSendable { /// The `BareItem` that this `Item` contains. public var bareItem: BareItem @@ -106,7 +106,7 @@ extension Item: Hashable {} /// A `BareInnerList` represents the items contained within an `InnerList`, without /// the associated parameters. -public struct BareInnerList: Hashable, _Sendable { +public struct BareInnerList: Hashable, SHSendable { private var items: [Item] public init() { @@ -179,7 +179,7 @@ extension BareInnerList.Index: Comparable { // MARK: - InnerList /// An `InnerList` is a list of items, with some associated parameters. -public struct InnerList: Hashable, _Sendable { +public struct InnerList: Hashable, SHSendable { /// The items contained within this inner list. public var bareInnerList: BareInnerList diff --git a/Sources/RawStructuredFieldValues/Errors.swift b/Sources/RawStructuredFieldValues/Errors.swift index 825d4ff..a9359eb 100644 --- a/Sources/RawStructuredFieldValues/Errors.swift +++ b/Sources/RawStructuredFieldValues/Errors.swift @@ -15,7 +15,7 @@ // MARK: - StructuredHeaderError /// Errors that may be encountered when working with structured headers. -public struct StructuredHeaderError: Error, _Sendable { +public struct StructuredHeaderError: Error, SHSendable { private enum _BaseError: Hashable { case invalidTrailingBytes case invalidInnerList diff --git a/Sources/RawStructuredFieldValues/FieldParser.swift b/Sources/RawStructuredFieldValues/FieldParser.swift index 986e9bf..b24a0e9 100644 --- a/Sources/RawStructuredFieldValues/FieldParser.swift +++ b/Sources/RawStructuredFieldValues/FieldParser.swift @@ -25,7 +25,7 @@ public struct StructuredFieldValueParser where } } -extension StructuredFieldValueParser: _Sendable where BaseData: _Sendable, BaseData.SubSequence: _Sendable { +extension StructuredFieldValueParser: SHSendable where BaseData: SHSendable, BaseData.SubSequence: SHSendable { } diff --git a/Sources/RawStructuredFieldValues/FieldSerializer.swift b/Sources/RawStructuredFieldValues/FieldSerializer.swift index c02d6e2..3bff96e 100644 --- a/Sources/RawStructuredFieldValues/FieldSerializer.swift +++ b/Sources/RawStructuredFieldValues/FieldSerializer.swift @@ -15,7 +15,7 @@ private let validIntegerRange = Int64(-999_999_999_999_999) ... Int64(999_999_999_999_999) /// A `StructuredFieldValueSerializer` is the basic parsing object for structured header field values. -public struct StructuredFieldValueSerializer: _Sendable { +public struct StructuredFieldValueSerializer: SHSendable { private var data: [UInt8] public init() { diff --git a/Sources/RawStructuredFieldValues/OrderedMap.swift b/Sources/RawStructuredFieldValues/OrderedMap.swift index 580a0cb..7aaf152 100644 --- a/Sources/RawStructuredFieldValues/OrderedMap.swift +++ b/Sources/RawStructuredFieldValues/OrderedMap.swift @@ -23,7 +23,7 @@ /// Note that this preserves _original_ insertion order: if you overwrite a key's value, the /// key does not move to "last". This is a specific requirement for Structured Headers and may /// harm the generality of this implementation. -public struct OrderedMap: _Sendable where Key: Hashable { +public struct OrderedMap: SHSendable where Key: Hashable { private var backing: [Entry] public init() { @@ -70,7 +70,7 @@ extension OrderedMap { // MARK: - Collection conformances extension OrderedMap: RandomAccessCollection, MutableCollection { - public struct Index: _Sendable { + public struct Index: SHSendable { fileprivate var baseIndex: Array<(Key, Value)>.Index fileprivate init(_ baseIndex: Array<(Key, Value)>.Index) { diff --git a/Sources/RawStructuredFieldValues/PseudoDecimal.swift b/Sources/RawStructuredFieldValues/PseudoDecimal.swift index 38d6feb..c3884c9 100644 --- a/Sources/RawStructuredFieldValues/PseudoDecimal.swift +++ b/Sources/RawStructuredFieldValues/PseudoDecimal.swift @@ -34,7 +34,7 @@ import Glibc /// is 999,999,999,999,999. The exponent ranges from -3 to 0. Additionally, there may be no more than 12 decimal digits before /// the decimal place, so while the maximum value of the significand is 999,999,999,999,999, that is only acceptable if the /// exponent is -3. -public struct PseudoDecimal: Hashable, _Sendable { +public struct PseudoDecimal: Hashable, SHSendable { private var _mantissa: Int64 private var _exponent: Int8 diff --git a/Sources/RawStructuredFieldValues/Sendable.swift b/Sources/RawStructuredFieldValues/Sendable.swift index fd6fe58..6cf706d 100644 --- a/Sources/RawStructuredFieldValues/Sendable.swift +++ b/Sources/RawStructuredFieldValues/Sendable.swift @@ -13,7 +13,7 @@ //===----------------------------------------------------------------------===// #if swift(>=5.5) && canImport(_Concurrency) -public typealias _Sendable = Sendable +public typealias SHSendable = Sendable #else -public typealias _Sendable = Any +public typealias SHSendable = Any #endif diff --git a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift index e14f604..05e24bd 100644 --- a/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift +++ b/Sources/StructuredFieldValues/Decoder/StructuredFieldValueDecoder.swift @@ -16,7 +16,7 @@ import RawStructuredFieldValues /// A `StructuredFieldValueDecoder` allows decoding `Decodable` objects from a HTTP /// structured header field. -public struct StructuredFieldValueDecoder: _Sendable { +public struct StructuredFieldValueDecoder: SHSendable { /// A strategy that should be used to map coding keys to wire format keys. public var keyDecodingStrategy: KeyDecodingStrategy? @@ -25,7 +25,7 @@ public struct StructuredFieldValueDecoder: _Sendable { extension StructuredFieldValueDecoder { /// A strategy that should be used to map coding keys to wire format keys. - public struct KeyDecodingStrategy: Hashable, _Sendable { + public struct KeyDecodingStrategy: Hashable, SHSendable { fileprivate enum Base: Hashable { case lowercase } diff --git a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift index e6c1371..74ccde7 100644 --- a/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift +++ b/Sources/StructuredFieldValues/Encoder/StructuredFieldValueEncoder.swift @@ -16,7 +16,7 @@ import RawStructuredFieldValues /// A `StructuredFieldValueEncoder` allows encoding `Encodable` objects to the format of a HTTP /// structured header field. -public struct StructuredFieldValueEncoder: _Sendable { +public struct StructuredFieldValueEncoder: SHSendable { public var keyEncodingStrategy: KeyEncodingStrategy? public init() {} @@ -24,7 +24,7 @@ public struct StructuredFieldValueEncoder: _Sendable { extension StructuredFieldValueEncoder { /// A strategy that should be used to map coding keys to wire format keys. - public struct KeyEncodingStrategy: Hashable, _Sendable { + public struct KeyEncodingStrategy: Hashable, SHSendable { fileprivate enum Base: Hashable { case lowercase } From fcfdadfdc3d91c5da13ab665c526afb504fb22ff Mon Sep 17 00:00:00 2001 From: David Evans Date: Thu, 12 May 2022 12:54:54 +0100 Subject: [PATCH 4/7] Fix date checking --- scripts/soundness.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/soundness.sh b/scripts/soundness.sh index dc1da78..7766899 100755 --- a/scripts/soundness.sh +++ b/scripts/soundness.sh @@ -17,7 +17,7 @@ set -eu here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" function replace_acceptable_years() { # this needs to replace all acceptable forms with 'YEARS' - sed -e 's/2020-2021/YEARS/' -e 's/202[01]/YEARS/' + sed -e 's/202[01]-202[012]/YEARS/' -e 's/202[012]/YEARS/' } From 6bcf442b9cc3f46f0e815d59b544e781075a54b7 Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 6 May 2022 14:18:07 +0100 Subject: [PATCH 5/7] Fix warning --- Sources/RawStructuredFieldValues/OrderedMap.swift | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/Sources/RawStructuredFieldValues/OrderedMap.swift b/Sources/RawStructuredFieldValues/OrderedMap.swift index 7aaf152..732ad91 100644 --- a/Sources/RawStructuredFieldValues/OrderedMap.swift +++ b/Sources/RawStructuredFieldValues/OrderedMap.swift @@ -23,7 +23,7 @@ /// Note that this preserves _original_ insertion order: if you overwrite a key's value, the /// key does not move to "last". This is a specific requirement for Structured Headers and may /// harm the generality of this implementation. -public struct OrderedMap: SHSendable where Key: Hashable { +public struct OrderedMap where Key: Hashable { private var backing: [Entry] public init() { @@ -67,6 +67,10 @@ extension OrderedMap { } } +extension OrderedMap: SHSendable where Key: SHSendable, Value: SHSendable {} + +extension OrderedMap.Entry: SHSendable where Key: SHSendable, Value: SHSendable {} + // MARK: - Collection conformances extension OrderedMap: RandomAccessCollection, MutableCollection { From 9e3eb0b3e35a06e9ccd778e5e327b30f12ff7b92 Mon Sep 17 00:00:00 2001 From: David Evans Date: Thu, 12 May 2022 12:57:24 +0100 Subject: [PATCH 6/7] Soundness --- Sources/RawStructuredFieldValues/FieldParser.swift | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/Sources/RawStructuredFieldValues/FieldParser.swift b/Sources/RawStructuredFieldValues/FieldParser.swift index b24a0e9..4b3be0a 100644 --- a/Sources/RawStructuredFieldValues/FieldParser.swift +++ b/Sources/RawStructuredFieldValues/FieldParser.swift @@ -25,9 +25,7 @@ public struct StructuredFieldValueParser where } } -extension StructuredFieldValueParser: SHSendable where BaseData: SHSendable, BaseData.SubSequence: SHSendable { - -} +extension StructuredFieldValueParser: SHSendable where BaseData: SHSendable, BaseData.SubSequence: SHSendable {} extension StructuredFieldValueParser { // Helper typealiases to avoid the explosion of generic parameters From db27387337ef6b9db1f4436ea240f5824180d43b Mon Sep 17 00:00:00 2001 From: David Evans Date: Fri, 13 May 2022 11:06:10 +0100 Subject: [PATCH 7/7] Update date Co-authored-by: Cory Benfield --- Sources/RawStructuredFieldValues/Sendable.swift | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Sources/RawStructuredFieldValues/Sendable.swift b/Sources/RawStructuredFieldValues/Sendable.swift index 6cf706d..6ff80ec 100644 --- a/Sources/RawStructuredFieldValues/Sendable.swift +++ b/Sources/RawStructuredFieldValues/Sendable.swift @@ -2,7 +2,7 @@ // // This source file is part of the SwiftNIO open source project // -// Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors +// Copyright (c) 2022 Apple Inc. and the SwiftNIO project authors // Licensed under Apache License v2.0 // // See LICENSE.txt for license information