Skip to content

Commit

Permalink
Drop support for Swift <5.9 (#172)
Browse files Browse the repository at this point in the history
Xcode 15 has been required for App Store submissions since April, so
let's simplify things.
  • Loading branch information
stephencelis authored Jun 14, 2024
1 parent b893b62 commit 59ab7db
Show file tree
Hide file tree
Showing 13 changed files with 546 additions and 896 deletions.
5 changes: 2 additions & 3 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,7 @@ jobs:
strategy:
matrix:
xcode:
- '14.3.1'
- '15.2'
- '15.4'
steps:
- uses: actions/checkout@v4
- name: Select Xcode ${{ matrix.xcode }}
Expand All @@ -35,7 +34,7 @@ jobs:
strategy:
matrix:
swift:
- '5.9'
- '5.10'
name: Ubuntu (Swift ${{ matrix.swift }})
runs-on: ubuntu-latest
container: swift:${{ matrix.swift }}
Expand Down
36 changes: 33 additions & 3 deletions Package.swift
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
// swift-tools-version: 5.6
// swift-tools-version: 5.9

import CompilerPluginSupport
import PackageDescription

let package = Package(
Expand All @@ -17,19 +18,36 @@ let package = Package(
)
],
dependencies: [
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0")
.package(url: "https://github.com/apple/swift-syntax", "509.0.0"..<"601.0.0"),
.package(url: "https://github.com/pointfreeco/swift-macro-testing", from: "0.2.0"),
.package(url: "https://github.com/pointfreeco/xctest-dynamic-overlay", from: "1.0.0"),
],
targets: [
.target(
name: "CasePaths",
dependencies: [
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay")
"CasePathsMacros",
.product(name: "XCTestDynamicOverlay", package: "xctest-dynamic-overlay"),
]
),
.testTarget(
name: "CasePathsTests",
dependencies: ["CasePaths"]
),
.macro(
name: "CasePathsMacros",
dependencies: [
.product(name: "SwiftSyntaxMacros", package: "swift-syntax"),
.product(name: "SwiftCompilerPlugin", package: "swift-syntax"),
]
),
.testTarget(
name: "CasePathsMacrosTests",
dependencies: [
"CasePathsMacros",
.product(name: "MacroTesting", package: "swift-macro-testing"),
]
),
]
)

Expand All @@ -39,3 +57,15 @@ let package = Package(
.package(url: "https://github.com/apple/swift-docc-plugin", from: "1.0.0")
)
#endif

for target in package.targets {
target.swiftSettings = target.swiftSettings ?? []
target.swiftSettings?.append(contentsOf: [
.enableExperimentalFeature("StrictConcurrency")
])
// target.swiftSettings?.append(
// .unsafeFlags([
// "-enable-library-evolution",
// ])
// )
}
71 changes: 0 additions & 71 deletions Package@swift-5.9.swift

This file was deleted.

110 changes: 37 additions & 73 deletions Sources/CasePaths/AnyCasePath.swift
Original file line number Diff line number Diff line change
Expand Up @@ -63,80 +63,44 @@ extension AnyCasePath: CustomDebugStringConvertible {
#endif

extension AnyCasePath {
#if swift(>=5.9)
@available(
iOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
macOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
tvOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
watchOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
public func modify<Result>(
_ root: inout Root,
_ body: (inout Value) throws -> Result
) throws -> Result {
guard var value = self.extract(from: root) else { throw ExtractionFailed() }
let result = try body(&value)
root = self.embed(value)
return result
}
#else
/// Attempts to modify a value in a root.
///
/// - Parameters:
/// - root: A root to modify if the case path matches.
/// - body: A closure that can mutate the case's associated value. If the closure throws, the
/// root will be left unmodified.
/// - Returns: The return value, if any, of the body closure.
public func modify<Result>(
_ root: inout Root,
_ body: (inout Value) throws -> Result
) throws -> Result {
guard var value = self.extract(from: root) else { throw ExtractionFailed() }
let result = try body(&value)
root = self.embed(value)
return result
}
#endif
@available(
iOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
macOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
tvOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
@available(
watchOS, deprecated: 9999,
message: "Use 'CasePathable.modify', or 'extract' and 'embed', instead."
)
public func modify<Result>(
_ root: inout Root,
_ body: (inout Value) throws -> Result
) throws -> Result {
guard var value = self.extract(from: root) else { throw ExtractionFailed() }
let result = try body(&value)
root = self.embed(value)
return result
}

#if swift(>=5.9)
@available(iOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(macOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(tvOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(watchOS, deprecated: 9999, message: "Chain case key paths together, instead.")
public func appending<AppendedValue>(
path: AnyCasePath<Value, AppendedValue>
) -> AnyCasePath<Root, AppendedValue> {
AnyCasePath<Root, AppendedValue>(
embed: { self.embed(path.embed($0)) },
extract: { self.extract(from: $0).flatMap(path.extract) }
)
}
#else
/// Returns a new case path created by appending the given case path to this one.
///
/// Use this method to extend this case path to the value type of another case path.
///
/// - Parameter path: The case path to append.
/// - Returns: A case path from the root of this case path to the value type of `path`.
public func appending<AppendedValue>(
path: AnyCasePath<Value, AppendedValue>
) -> AnyCasePath<Root, AppendedValue> {
AnyCasePath<Root, AppendedValue>(
embed: { self.embed(path.embed($0)) },
extract: { self.extract(from: $0).flatMap(path.extract) }
)
}
#endif
@available(iOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(macOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(tvOS, deprecated: 9999, message: "Chain case key paths together, instead.")
@available(watchOS, deprecated: 9999, message: "Chain case key paths together, instead.")
public func appending<AppendedValue>(
path: AnyCasePath<Value, AppendedValue>
) -> AnyCasePath<Root, AppendedValue> {
AnyCasePath<Root, AppendedValue>(
embed: { self.embed(path.embed($0)) },
extract: { self.extract(from: $0).flatMap(path.extract) }
)
}
}

struct ExtractionFailed: Error {}
24 changes: 8 additions & 16 deletions Sources/CasePaths/CasePathable.swift
Original file line number Diff line number Diff line change
Expand Up @@ -43,22 +43,14 @@ public protocol CasePathable {
static var allCasePaths: AllCasePaths { get }
}

#if swift(>=5.9)
/// A type that is used to distinguish case key paths from key paths by wrapping the enum and
/// associated value types.
@_documentation(visibility:internal)
@dynamicMemberLookup
public struct Case<Value>: Sendable {
fileprivate let _embed: @Sendable (Value) -> Any
fileprivate let _extract: @Sendable (Any) -> Value?
}
#else
@dynamicMemberLookup
public struct Case<Value> {
fileprivate let _embed: @Sendable (Value) -> Any
fileprivate let _extract: @Sendable (Any) -> Value?
}
#endif
/// A type that is used to distinguish case key paths from key paths by wrapping the enum and
/// associated value types.
@_documentation(visibility:internal)
@dynamicMemberLookup
public struct Case<Value>: Sendable {
fileprivate let _embed: @Sendable (Value) -> Any
fileprivate let _extract: @Sendable (Any) -> Value?
}

extension Case {
public init<Root>(
Expand Down
7 changes: 1 addition & 6 deletions Sources/CasePaths/EnumReflection.swift
Original file line number Diff line number Diff line change
Expand Up @@ -222,12 +222,7 @@ private struct MetadataKind: Equatable {
}

@_spi(Reflection) public func tag<Enum>(of value: Enum) -> UInt32 {
#if swift(<5.8)
// NB: Workaround for https://github.com/apple/swift/issues/61708
guard self.typeDescriptor.emptyCaseCount + self.typeDescriptor.payloadCaseCount > 1
else { return 0 }
#endif
return withUnsafePointer(to: value) {
withUnsafePointer(to: value) {
self.valueWitnessTable.getEnumTag($0, self.ptr)
}
}
Expand Down
Loading

0 comments on commit 59ab7db

Please sign in to comment.