Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Swift Language Support: Drop <5.9, Add 6.0 #73

Merged
merged 2 commits into from
Jun 18, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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