Skip to content

Commit

Permalink
Swift Language Support: Drop <5.9, Add 6.0 (#73)
Browse files Browse the repository at this point in the history
* wip

* wip
  • Loading branch information
stephencelis authored Jun 18, 2024
1 parent cc86299 commit 3953620
Show file tree
Hide file tree
Showing 10 changed files with 95 additions and 38 deletions.
16 changes: 8 additions & 8 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,20 +10,20 @@ on:

jobs:
build:
name: MacOS
runs-on: macos-13
name: macOS
runs-on: macos-14
steps:
- uses: actions/checkout@v4
- name: Select Xcode 15.2
run: sudo xcode-select -s /Applications/Xcode_15.2.app
- name: Select Xcode 15.4
run: sudo xcode-select -s /Applications/Xcode_15.4.app
- name: Run tests
run: make test-swift

ubuntu:
strategy:
matrix:
swift:
- '5.9'
- '5.10'
name: Ubuntu (Swift ${{ matrix.swift }})
runs-on: ubuntu-latest
container: swift:${{ matrix.swift }}
Expand All @@ -35,7 +35,7 @@ jobs:
run: swift test -c release --parallel

windows:
name: Windows (Swift ${{ matrix.swfit }}, ${{ matrix.config }})
name: Windows (Swift ${{ matrix.swift }}, ${{ matrix.config }})
strategy:
matrix:
os: [windows-latest]
Expand All @@ -45,8 +45,8 @@ jobs:
steps:
- uses: compnerd/gha-setup-swift@main
with:
branch: swift-5.9.1-release
tag: 5.9.1-RELEASE
branch: swift-5.10-release
tag: 5.10-RELEASE
- uses: actions/checkout@v4
- name: Build
run: swift build -c ${{ matrix.config }}
Expand Down
9 changes: 8 additions & 1 deletion Package.swift
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
// swift-tools-version:5.6
// swift-tools-version: 5.9

import PackageDescription

Expand Down Expand Up @@ -35,6 +35,13 @@ let package = Package(
]
)

for target in package.targets {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings!.append(contentsOf: [
.enableExperimentalFeature("StrictConcurrency")
])
}

#if !os(Windows)
// DocC needs to be ported to Windows
// https://github.com/thebrowsercompany/swift-build/issues/39
Expand Down
45 changes: 45 additions & 0 deletions [email protected]
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
// swift-tools-version: 6.0

import PackageDescription

let package = Package(
name: "swift-identified-collections",
products: [
.library(
name: "IdentifiedCollections",
targets: ["IdentifiedCollections"]
)
],
dependencies: [
.package(url: "https://github.com/apple/swift-collections", from: "1.0.2"),
.package(url: "https://github.com/apple/swift-collections-benchmark", from: "0.0.2"),
],
targets: [
.target(
name: "IdentifiedCollections",
dependencies: [
.product(name: "OrderedCollections", package: "swift-collections")
]
),
.testTarget(
name: "IdentifiedCollectionsTests",
dependencies: ["IdentifiedCollections"]
),
.executableTarget(
name: "swift-identified-collections-benchmark",
dependencies: [
"IdentifiedCollections",
.product(name: "CollectionsBenchmark", package: "swift-collections-benchmark"),
]
),
],
swiftLanguageVersions: [.v6]
)

#if !os(Windows)
// DocC needs to be ported to Windows
// https://github.com/thebrowsercompany/swift-build/issues/39
package.dependencies.append(
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
)
#endif
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,10 @@ extension IdentifiedArray {
/// implements high-quality hashing.
@inlinable
@_disfavoredOverload
public init<S>(
uncheckedUniqueElements elements: S,
public init(
uncheckedUniqueElements elements: some Sequence<Element>,
id: KeyPath<Element, ID>
)
where S: Sequence, S.Element == Element {
) {
self.init(
id: id,
_id: { $0[keyPath: id] },
Expand All @@ -46,11 +45,10 @@ extension IdentifiedArray {
/// - Complexity: Expected O(*n*) on average, where *n* is the count of elements, if `ID`
/// implements high-quality hashing.
@inlinable
public init<S>(
public init<S: Sequence<Element>>(
uniqueElements elements: S,
id: KeyPath<Element, ID>
)
where S: Sequence, S.Element == Element {
) {
if S.self == Self.self {
self = elements as! Self
return
Expand Down Expand Up @@ -82,11 +80,11 @@ extension IdentifiedArray {
/// - Returns: A new array initialized with the unique elements of `elements`.
/// - Complexity: Expected O(*n*) on average, where *n* is the count of elements, if `ID`
/// implements high-quality hashing.
public init<S: Sequence>(
_ elements: S,
public init(
_ elements: some Sequence<Element>,
id: KeyPath<Element, ID>,
uniquingIDsWith combine: (Element, Element) throws -> Element
) rethrows where S.Element == Element {
) rethrows {
try self.init(
id: id,
_id: { $0[keyPath: id] },
Expand Down Expand Up @@ -146,7 +144,7 @@ extension IdentifiedArray where Element: Identifiable, ID == Element.ID {
/// implements high-quality hashing.
@inlinable
@_disfavoredOverload
public init<S>(uncheckedUniqueElements elements: S) where S: Sequence, S.Element == Element {
public init(uncheckedUniqueElements elements: some Sequence<Element>) {
self.init(
id: \.id,
_id: { $0.id },
Expand All @@ -166,7 +164,7 @@ extension IdentifiedArray where Element: Identifiable, ID == Element.ID {
/// - Complexity: Expected O(*n*) on average, where *n* is the count of elements, if `ID`
/// implements high-quality hashing.
@inlinable
public init<S>(uniqueElements elements: S) where S: Sequence, S.Element == Element {
public init<S: Sequence<Element>>(uniqueElements elements: S) {
if S.self == Self.self {
self = elements as! Self
return
Expand Down Expand Up @@ -198,10 +196,10 @@ extension IdentifiedArray where Element: Identifiable, ID == Element.ID {
/// - Complexity: Expected O(*n*) on average, where *n* is the count of elements, if `ID`
/// implements high-quality hashing.
@inlinable
public init<S: Sequence>(
_ elements: S,
public init(
_ elements: some Sequence<Element>,
uniquingIDsWith combine: (Element, Element) throws -> Element
) rethrows where S.Element == Element {
) rethrows {
try self.init(
id: \.id,
_id: { $0.id },
Expand All @@ -217,15 +215,15 @@ extension IdentifiedArray where Element: Identifiable, ID == Element.ID {

extension IdentifiedArray {
@available(*, deprecated, renamed: "init(uniqueElements:id:)")
public init<S>(_ elements: S, id: KeyPath<Element, ID>) where S: Sequence, S.Element == Element {
public init(_ elements: some Sequence<Element>, id: KeyPath<Element, ID>) {
self.init(uniqueElements: elements, id: id)
}
}

@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
extension IdentifiedArray where Element: Identifiable, ID == Element.ID {
@available(*, deprecated, renamed: "init(uniqueElements:)")
public init<S>(_ elements: S) where S: Sequence, S.Element == Element {
public init(_ elements: some Sequence<Element>) {
self.init(uniqueElements: elements)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@ extension IdentifiedArray {
/// - Complexity: The operation is expected to perform amortized O(1) copy, hash, and compare
/// operations on the `Element` type, if it implements high-quality hashing.
@inlinable
public mutating func append<S>(contentsOf newElements: S)
where Element == S.Element, S: Sequence {
public mutating func append(contentsOf newElements: some Sequence<Element>) {
self.reserveCapacity(self.count + newElements.underestimatedCount)
for element in newElements {
self.append(element)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,9 @@ where Element: Identifiable, ID == Element.ID {
}

@inlinable
public mutating func replaceSubrange<C: Collection>(_ subrange: Range<Int>, with newElements: C)
where C.Element == Element {
public mutating func replaceSubrange(
_ subrange: Range<Int>, with newElements: some Collection<Element>
) {
self._dictionary.removeSubrange(subrange)
self._dictionary.reserveCapacity(self.count + newElements.count)
for element in newElements.reversed() {
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
#if swift(>=5.5)
extension IdentifiedArray: @unchecked Sendable
where ID: Sendable, Element: Sendable {}
#endif
extension IdentifiedArray: @unchecked Sendable
where ID: Sendable, Element: Sendable {}
Original file line number Diff line number Diff line change
Expand Up @@ -261,7 +261,7 @@ import OrderedCollections
/// should not be mutated in place, as it will drift from its associated dictionary key. Identified
/// array is designed to avoid this invariant, with the exception of its *id-based* subscript.
/// Mutating an element's id will result in a runtime error.
public struct IdentifiedArray<ID, Element> where ID: Hashable {
public struct IdentifiedArray<ID: Hashable, Element> {
public let id: KeyPath<Element, ID>

// NB: Captures identity access. Direct access to `Identifiable`'s `.id` property is faster than
Expand Down
9 changes: 7 additions & 2 deletions Sources/swift-identified-collections-benchmark/main.swift
Original file line number Diff line number Diff line change
@@ -1,8 +1,13 @@
import CollectionsBenchmark
import IdentifiedCollections

@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
extension Int: Identifiable { public var id: Self { self } }
#if $RetroactiveAttribute
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
extension Int: @retroactive Identifiable { public var id: Self { self } }
#else
@available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *)
extension Int: Identifiable { public var id: Self { self } }
#endif

if #available(iOS 13, macOS 10.15, tvOS 13, watchOS 6, *) {
var benchmark = Benchmark(title: "Identified Collections Benchmark")
Expand Down
6 changes: 5 additions & 1 deletion Tests/IdentifiedCollectionsTests/IdentifiedArrayTests.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ import XCTest

@testable import IdentifiedCollections

extension Int: Identifiable { public var id: Self { self } }
#if $RetroactiveAttribute
extension Int: @retroactive Identifiable { public var id: Self { self } }
#else
extension Int: Identifiable { public var id: Self { self } }
#endif

private struct User: Equatable, Identifiable {
let id: Int
Expand Down

0 comments on commit 3953620

Please sign in to comment.