Closure typing changed in Swift 3


(Rick M) #1

I have some code that implements an HTTP server. You use it like this:

server["/some/path"] =
{ inReq in
    return .ok(.json(["key" : "value"]))
}

".ok" is a case in the HttpResponse enum.

The subscript on "server" above looks like this:

class HttpServer {
    typealias Handler = (HttpRequest) -> HttpResponse

    subscript (path: String) -> Handler?
    {
        get { return nil }
        set ( newValue )
        {
            ...store in dictionary of path:Handler...
        }
    }
}

Unfortunately, in Swift 3, I get "Cannot assign value of type '(_) -> _' to type 'HttpServer.Handler?'"

It seems the type inference is working differently? I tried { (inReq: HttpRequest) in ... }, but I got the same error with a slightly different type signature.

Can anyone tell me what's changed?

TIA,

···

--
Rick Mann
rmann@latencyzero.com


(Rick M) #2

I figured it out. The real problem is that .json accepts AnyObject, and the Dictionary is not AnyObject (not sure what this change is, since it worked in Swift 2). Anyway, that confused the type inference, which resulted in the red herring error message about the closure assignment.

···

On Sep 9, 2016, at 14:34 , Rick Mann via swift-users <swift-users@swift.org> wrote:

I have some code that implements an HTTP server. You use it like this:

server["/some/path"] =
{ inReq in
  return .ok(.json(["key" : "value"]))
}

".ok" is a case in the HttpResponse enum.

The subscript on "server" above looks like this:

class HttpServer {
  typealias Handler = (HttpRequest) -> HttpResponse

  subscript (path: String) -> Handler?
  {
      get { return nil }
      set ( newValue )
      {
          ...store in dictionary of path:Handler...
      }
  }
}

Unfortunately, in Swift 3, I get "Cannot assign value of type '(_) -> _' to type 'HttpServer.Handler?'"

It seems the type inference is working differently? I tried { (inReq: HttpRequest) in ... }, but I got the same error with a slightly different type signature.

Can anyone tell me what's changed?

TIA,

--
Rick Mann
rmann@latencyzero.com

_______________________________________________
swift-users mailing list
swift-users@swift.org
https://lists.swift.org/mailman/listinfo/swift-users

--
Rick

--
Rick Mann
rmann@latencyzero.com


(Greg Parker) #3

What changed is Objective-C bridging. Previously the compiler could convert Dictionary to NSDictionary to AnyObject. Now that path is no longer implicitly available.

···

On Sep 9, 2016, at 8:05 PM, Rick Mann via swift-users <swift-users@swift.org> wrote:

I figured it out. The real problem is that .json accepts AnyObject, and the Dictionary is not AnyObject (not sure what this change is, since it worked in Swift 2). Anyway, that confused the type inference, which resulted in the red herring error message about the closure assignment.

--
Greg Parker gparker@apple.com <mailto:gparker@apple.com> Runtime Wrangler