pointfreeco / swift-case-paths

🧰 Case paths extends the key path hierarchy to enum cases.
https://www.pointfree.co/collections/enums-and-structs/case-paths
MIT License
904 stars 105 forks source link

Fix build warning when `@CasePathable` is applied to enums with no cases #164

Closed jpsim closed 3 months ago

jpsim commented 3 months ago

Fixes warnings due to unreachable code introduced in 1.4.0:

For example:

@CasePathable enum Foo {}

Produces this expansion (compiler warnings added as code comments by me)

enum Foo: CasePathable {
  public struct AllCasePaths: Sequence {
    public subscript(root: Foo) -> PartialCaseKeyPath<Foo> {
      return \.never // ⚠️ warning: will never be executed
      // 'root' is of type 'Foo' which cannot be constructed because it
      // is an enum with no cases
    }

    public func makeIterator() -> IndexingIterator<[PartialCaseKeyPath<Foo>]> {
      let allCasePaths: [PartialCaseKeyPath<Foo>] = []
      return allCasePaths.makeIterator()
    }
  }
  public static var allCasePaths: AllCasePaths { AllCasePaths() }
}

We can fix this warning by simply not producing the subscript definition when the enum has no cases.

stephencelis commented 3 months ago

Hey @jpsim! For some reason these diagnostics are really thorny, and probably warrant some bug reports to Swift. For example, this compiles without warning:

func never<A>(never: Never) -> A {}

enum Foo {}
func never<A>(never: Foo) -> A {}

So I think technically this should compile, but it doesn't:

enum Never {
  static subscript<A>(never: Foo) -> A {
}

I'll file a bug soon.

Ideally we'd be able to have the implementation of this subscript regardless, since we eventually want to abstract it on the CasePathable protocol. We're just delaying that work, probably to 2.0, since it feels like a breaking change to folks with manual conformances.

I have found that omitting the return statement and still returning \.never silences the warning, though:

 public subscript(root: Foo) -> PartialCaseKeyPath<Foo> {
-  return \.never
+  \.never

Can you try making that change and confirm?

jpsim commented 3 months ago

Thanks for the details! I'll give that a shot.

stephencelis commented 3 months ago

https://github.com/apple/swift/issues/74210