swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.35k stars 10.34k forks source link

[5.8] Unable to infer closure parameter type regression #63727

Open keith opened 1 year ago

keith commented 1 year ago

With this code:

struct Foo {
    let child: Child?

    init(child: Child?) {
        self.child = child
    }

    enum Child {
        case `bar`(String)
        case `baz`(String)
    }

    func childValueType() -> Any.Type {
        return self.child
            .flatMap { child -> Any? in
                let mirror = Mirror(reflecting: child)
                guard mirror.displayStyle == .enum, let child = mirror.children.first else {
                    return nil
                }

                return child.value
            }
            .flatMap { featureElement in
                let mirror = Mirror(reflecting: featureElement)
                guard mirror.displayStyle == .struct,
                      let child = mirror.children.first, child.label == "element"
                else {
                    return nil
                }

                return child.value
            }
            .flatMap { child -> Any? in
                let mirror = Mirror(reflecting: child)
                guard mirror.displayStyle == .optional, let child = mirror.children.first else {
                    return nil
                }

                return child.value
            }
            .flatMap { child -> Any.Type? in
                let mirror = Mirror(reflecting: child)
                guard mirror.displayStyle == .enum, let child = mirror.children.first else {
                    return nil
                }

                return type(of: child.value)
            } ?? type(of: self.child)
    }
}

You get this error when attempting to compile with Swift 5.8 from Xcode 14.3.0 beta 1:

% DEVELOPER_DIR=/Applications/Xcode-14.3.0-beta1.app swiftc foo.swift -o /tmp/foo
foo.swift:33:24: error: unable to infer type of a closure parameter 'child' in the current context
            .flatMap { child -> Any? in
                       ^
foo.swift:15:14: error: generic parameter 'U' could not be inferred
            .flatMap { child -> Any? in
             ^

But it compiles fine with Swift 5.7

AnthonyLatsis commented 1 year ago

Reduced:

do {
  let x: Int?
  let _: Int? = x
      .flatMap { x in
        if true {
          return nil
        }

        return Int?.none
      }
      .flatMap { x -> Int? in
        return Int?.none
      }
}