Skip to content

Add CaseIterable conformance to Platform #7084

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

Draft
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

Kyle-Ye
Copy link
Contributor

@Kyle-Ye Kyle-Ye commented Nov 13, 2023

Add CaseIterable conformance to Platform

Motivation:

Close #4478

Sometimes downstream package only cares about excluding a given platform (eg. wasi).

And each package need to maintain a supportedPlatforms array and update it when there is a platform added in SwiftPM(eg. visionOS).

We'd better fix it upstream here. And I think @neonichu's idea to add a CaseIterable conformance is great.

#4478 (comment)

Modifications:

Add CaseIterable conformance to Platform

@available(_PackageDescription, introduced: 5.11)
extension Platform: CaseIterable {
public static var allCases: [Platform] {
// Why visionOS does not need something like @available(_PackageDescription, introduced: 5.9)
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some question here:

  1. Why some new platform (eg. Platform.visionOS) is not marked with @available(_PackageDescription, introduced: 5.x) while some is marked(eg. Platform.openbsd)
  2. We can't use if #available(_PackageDescription 5.2, *) currently. When a new platform is introduced on Swift 5.11 and is marked as @available(_PackageDescription, introduced: 5.11), how can I append it conditionally?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. That seems like a mistake.
  2. I think we would need #available support to make this work.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Got it. Then maybe I can add check the time when they are added and add the corresponding available mark in this PR.
  2. if #avaiable(_PackageDescription 5.2, *) is currently not a valid Swift statement and a Swift Proposal for this may be needed.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've seen some usage on Swift repo with if #available(SwiftStdlib 5.3, *) maybe it is already supported upstream 🤔 and all we should do is add some flag?

Copy link
Contributor Author

@Kyle-Ye Kyle-Ye Jan 1, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

let availabilityDefinition = PackageDescription.SwiftSetting.unsafeFlags([
    "-Xfrontend",
    "-define-availability",
    "-Xfrontend",
    "SwiftStdlib 5.7:macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0",
    "-Xfrontend",
    "-define-availability",
    "-Xfrontend",
    "SwiftStdlib 5.8:macOS 13.3, iOS 16.4, watchOS 9.4, tvOS 16.4",
    "-Xfrontend",
    "-define-availability",
    "-Xfrontend",
    "SwiftStdlib 5.9:macOS 9999, iOS 9999, watchOS 9999, tvOS 9999",
])

Found the trick here, looks like SwiftStdlib is just a typealias for the OS check.

@tomerd
Copy link
Contributor

tomerd commented Dec 8, 2023

@Kyle-Ye @neonichu what are the next steps on this PR?

@neonichu
Copy link
Contributor

neonichu commented Dec 8, 2023

Not sure we have a path forward without compiler changes to support #avaiable for PackageDescription availability or some other way to access the selected API level.

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 9, 2023

Not sure we have a path forward without compiler changes to support #avaiable for PackageDescription availability or some other way to access the selected API level.

As @neonichu said, for the Darwin platform (eg. macOS) we can check the availability in the runtime via if #available. However such ability is currently not support for PackageDescription.

eg. SwiftUI/ControlSize on macOS platform

@available(macOS 10.15, *)
public enum ControlSize: CaseIterable {
    case mini
    case small
    @available(macOS 11, *)
    case large

    public static var allCases: [ControlSize] = {
        // ✅ Supported
        if #available(macOS 11, *) {
            return [.mini, .small, .large]
        } else {
            return [.mini, .small]
        }
    }()
}

@available(_PackageDescription, introduced: 5.5)
public enum Platform: CaseIterable {
    case iOS
    @available(_PackageDescription, introduced: 5.11)
    case visionOS

    public static var allCases: [Platform] = {
		// ❌ Not supported. 
        // PackageDescription version checks not allowed in #available(...)
        if #available(_PackageDescription 5.11, *) {
            return [.iOS, .visionOS]
        } else {
            return [.iOS]
        }
    }()
}

cc @tomerd

@tomerd
Copy link
Contributor

tomerd commented Dec 11, 2023

should we then close this PR and/or open an issue asking for an enhancement request on the compiler?

@Kyle-Ye
Copy link
Contributor Author

Kyle-Ye commented Dec 11, 2023

I'll convert it back to a draft. And could you help file an issue asking for an enhancement request on the compiler?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

[SR-13814] Add the allPlatforms property to the Platform struct in PackageDescription
4 participants