Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't the swift compiler sometimes accept the shorthand argument name?

Tags:

swift

swift2

The array is : var closestAnnotations:[MKAnnotation]

I was wondering why the swift compiler won't accept :

    let closestStationAnnotations = closestAnnotations.filter({
        $0.dynamicType === StationAnnotation.self
    })

Cannot convert value of type (_) -> Bool to expected argument type (MKAnnotation) -> Bool

But accepts :

    let closestStationAnnotations = closestAnnotations.filter({
        (annotation : MKAnnotation) -> Bool in
        annotation.dynamicType === StationAnnotation.self
    })
like image 937
Matthieu Riegler Avatar asked Nov 09 '22 05:11

Matthieu Riegler


1 Answers

I have been trying out different versions of your code (using Xcode 7). The fix is obvious, using

let closestStationAnnotations = closestAnnotations.filter({
    $0 is StationAnnotation
})

which is the correct way to test types, works without any problems.

I have noticed that there is simple code that makes the error go away

let closestStationAnnotations = closestAnnotations.filter({
    print("\($0)")
    return ($0.dynamicType === StationAnnotation.self)
})

However, this doesn't work:

let closestStationAnnotations = closestAnnotations.filter({
    return ($0.dynamicType === StationAnnotation.self)
})

If you notice the error message, the compiler sees the closure as (_) -> Bool.

That leads me to the conclusion that the expression $0.dynamicType is somehow optimized out.

Most interestingly

let closestStationAnnotations = closestAnnotations.filter({
    return true
})

will trigger the same error.

So I think there are two compiler bugs:

  1. The compiler cannot infer the argument from the type of the array and that's wrong because (_) -> Bool should be considered as (Type) -> Bool when called on [Type].

  2. The compiler somehow optimizes $0.dynamicType out and that's obviously wrong.

like image 51
Sulthan Avatar answered Jan 04 '23 03:01

Sulthan