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

[SR-10183] Swift 5 Regression: Bad Optional Resolution/Inference #52585

Open
stephencelis opened this issue Mar 26, 2019 · 5 comments
Open

[SR-10183] Swift 5 Regression: Bad Optional Resolution/Inference #52585

stephencelis opened this issue Mar 26, 2019 · 5 comments
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 5.0 type checker Area → compiler: Semantic analysis

Comments

@stephencelis
Copy link
Contributor

Previous ID SR-10183
Radar rdar://problem/49340258
Original Reporter @stephencelis
Type Bug
Environment

Xcode 10.2 / Swift 5

Additional Detail from JIRA
Votes 0
Component/s Compiler
Labels Bug, 5.0Regression, TypeChecker
Assignee None
Priority Medium

md5: 728bd925e2c7fdb822abcee069cd6283

Issue Description:

Swift 5 required this explicit typing:

pointfreeco/pointfreeco@1982a9a

The full code:

 let userSubscription: EitherIO<Error, Models.Subscription> =
   user.subscriptionId
     .map(
       Current.database.fetchSubscriptionById
         >>> mapExcept(requireSome)
   )
   ?? throwE(unit) 

Without the explicit EitherIO<Error, Models.Subscription> hint, Swift 5 started thinking this was an Optional<EitherIO<Error, Models.Subscription>>.

While the code is opaque, the code base is fully open source and you can check it out and see for yourself!

The previous commit, which will fail due to the type being incorrectly inferred as optional:

pointfreeco/pointfreeco@c5d1297

@xedin
Copy link
Member

xedin commented Mar 27, 2019

@stephencelis What is the signature of `throwE` in this example? I grepped PointFreeCo and it seems to be coming from dependencies.

@stephencelis
Copy link
Contributor Author

@xedin
Copy link
Member

xedin commented Mar 27, 2019

Thank you!

@xedin
Copy link
Member

xedin commented Mar 27, 2019

I tried to reduce this example but it doesn't get deduced to be an optional, it picks ?? overload with non-optional default.

import Foundation

public struct Tagged<Tag, RawValue> {
  var rawValue: RawValue

  init(rawValue: RawValue) {
    self.rawValue = rawValue
  }

  func map<B>(_ f: (RawValue) -> B) -> Tagged<Tag, B> {
    return .init(rawValue: f(self.rawValue))
  }
}

struct Info {
  typealias Id = Tagged<Info, UUID>
}

struct S {
  var id: Info.Id?
}

enum Either<L, R> {
  case left(L)
  case right(R)
}

struct EitherIO<E, A> {}

func throwE<E, A>(_ x: E) -> EitherIO<E, A> {
  fatalError()
}

infix operator >>>
func >>> <A, B, C>(f: @escaping (A) -> B, g: @escaping (B) -> C) -> ((A) -> C) {
  fatalError()
}

func mapExcept<E, F, A, B>(_ f: @escaping (Either<E, A>) -> Either<F, B>) -> (EitherIO<E, A>) -> EitherIO<F, B> {
  fatalError()
}

func requireSome<A>(_ e: Either<Error, A?>) -> Either<Error, A> {
  fatalError()
}

struct Unit : Error {}

var unit = Unit()

func test(_ s: S, _ arg: @escaping (Info.Id) -> EitherIO<Error, Info?>) {
  let _ = s.id.map(arg >>> mapExcept(requireSome)) ?? throwE(unit)
}

@stephencelis It might be some conditional conformance involved which I missed.

@stephencelis
Copy link
Contributor Author

I couldn’t reduce either. Any chance you can pull down the repo to reproduce? If you encounter any issues please let me know!

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug A deviation from expected or documented behavior. Also: expected but undesirable behavior. compiler The Swift compiler in itself regression swift 5.0 type checker Area → compiler: Semantic analysis
Projects
None yet
Development

No branches or pull requests

3 participants