diff --git a/Sources/ArgumentParser/CMakeLists.txt b/Sources/ArgumentParser/CMakeLists.txt index 25022c0f..ea7d83f9 100644 --- a/Sources/ArgumentParser/CMakeLists.txt +++ b/Sources/ArgumentParser/CMakeLists.txt @@ -46,6 +46,7 @@ add_library(ArgumentParser Utilities/Platform.swift Utilities/SequenceExtensions.swift Utilities/StringExtensions.swift + Utilities/SwiftExtensions.swift Utilities/Tree.swift Validators/CodingKeyValidator.swift diff --git a/Sources/ArgumentParser/Parsable Types/ExpressibleByArgument.swift b/Sources/ArgumentParser/Parsable Types/ExpressibleByArgument.swift index 33d81e19..0f09b90a 100644 --- a/Sources/ArgumentParser/Parsable Types/ExpressibleByArgument.swift +++ b/Sources/ArgumentParser/Parsable Types/ExpressibleByArgument.swift @@ -10,7 +10,7 @@ //===----------------------------------------------------------------------===// /// A type that can be expressed as a command-line argument. -public protocol ExpressibleByArgument { +public protocol ExpressibleByArgument: _SendableMetatype { /// Creates a new instance of this type from a command-line-specified /// argument. init?(argument: String) diff --git a/Sources/ArgumentParser/Parsable Types/ParsableArguments.swift b/Sources/ArgumentParser/Parsable Types/ParsableArguments.swift index 7a476999..1154d627 100644 --- a/Sources/ArgumentParser/Parsable Types/ParsableArguments.swift +++ b/Sources/ArgumentParser/Parsable Types/ParsableArguments.swift @@ -13,7 +13,7 @@ /// /// When you implement a `ParsableArguments` type, all properties must be declared with /// one of the four property wrappers provided by the `ArgumentParser` library. -public protocol ParsableArguments: Decodable { +public protocol ParsableArguments: Decodable, _SendableMetatype { /// Creates an instance of this parsable type using the definitions /// given by each property's wrapper. init() diff --git a/Sources/ArgumentParser/Utilities/SwiftExtensions.swift b/Sources/ArgumentParser/Utilities/SwiftExtensions.swift new file mode 100644 index 00000000..b09403bf --- /dev/null +++ b/Sources/ArgumentParser/Utilities/SwiftExtensions.swift @@ -0,0 +1,17 @@ +//===----------------------------------------------------------------------===// +// +// This source file is part of the Swift Argument Parser open source project +// +// Copyright (c) 2020 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// +//===----------------------------------------------------------------------===// + +#if compiler(>=6.2) +/// Designates a type as having a sendable metatype. +public protocol _SendableMetatype: SendableMetatype {} +#else +public protocol _SendableMetatype {} +#endif diff --git a/Tests/ArgumentParserEndToEndTests/CustomParsingEndToEndTests.swift b/Tests/ArgumentParserEndToEndTests/CustomParsingEndToEndTests.swift index fe2e2a16..62d0d59d 100644 --- a/Tests/ArgumentParserEndToEndTests/CustomParsingEndToEndTests.swift +++ b/Tests/ArgumentParserEndToEndTests/CustomParsingEndToEndTests.swift @@ -35,10 +35,11 @@ extension Array where Element == Name { // MARK: - private struct Foo: ParsableCommand { - enum Subgroup: Equatable { + enum Subgroup: Equatable, Sendable { case first(Int) case second(Int) + @Sendable static func makeFirst(_ str: String) throws -> Subgroup { guard let value = Int(str) else { throw ValidationError("Not a valid integer for 'first'") @@ -46,6 +47,7 @@ private struct Foo: ParsableCommand { return .first(value) } + @Sendable static func makeSecond(_ str: String) throws -> Subgroup { guard let value = Int(str) else { throw ValidationError("Not a valid integer for 'second'") diff --git a/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift b/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift index c414941b..19883493 100644 --- a/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift +++ b/Tests/ArgumentParserUnitTests/HelpGenerationTests.swift @@ -148,6 +148,8 @@ extension HelpGenerationTests { enum OptionFlags: String, EnumerableFlag { case optional, required } enum Degree { case bachelor, graduate, doctorate + + @Sendable static func degreeTransform(_ string: String) throws -> Degree { switch string { case "bachelor": diff --git a/Tests/ArgumentParserUnitTests/UsageGenerationTests.swift b/Tests/ArgumentParserUnitTests/UsageGenerationTests.swift index 99d23f1e..d7cfae89 100644 --- a/Tests/ArgumentParserUnitTests/UsageGenerationTests.swift +++ b/Tests/ArgumentParserUnitTests/UsageGenerationTests.swift @@ -132,6 +132,7 @@ extension UsageGenerationTests { enum Color { case red, blue + @Sendable static func transform(_ string: String) throws -> Color { switch string { case "red":