Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Swift: EXC_BAD_ACCESS calling a method from a generic type that implements a protocol

I'm working on a project with Swift 2 and Xcode 7.3 and facing an error that I can't understand the reason yet.

I've created a protocol called Resource which has an associatedtype and a static var of that type.

Inside its extension, I'm trying to create a default implementation of the static var's getter, where the type is a generic struct that implements another protocol called ResourceFinderProtocol.

It all compiles good but, in runtime, when executing the last line of the snippet below, it produces a EXC_BAD_ACCESS crash.

If I make the struct ResourceFinder not generic, it works smoothly.

protocol Resource {
    associatedtype ResourceFinderType
    static var localObjects: ResourceFinderType { get }
}

extension Resource {
    static var localObjects: ResourceFinder<Self> {
        return ResourceFinder()
    }
}

public protocol ResourceFinderProtocol {
    associatedtype ResourceType
    func all() -> [ResourceType]
}

struct ResourceFinder<T:Resource>: ResourceFinderProtocol {
    func all() -> [T] {
        return []
    }
}

struct Model: Resource {}

Model.localObjects.all()

Any ideas of what can be happening here?

EDIT:

As Alexander pointed out, even if I split the call into:

let localObjects = Model.localObjects
let allObjects = localObjects.all()

... it still crashes in the first line.

like image 484
Gustavo Barbosa Avatar asked Apr 25 '16 15:04

Gustavo Barbosa


1 Answers

It is a compiler bug, resulting in a stack overflow when accessing the localObjects property. From what I can gather, it is an issue with a recursive dependency between your types, and more specifically that localObjects is invoked via dynamic dispatch. If I remove the static var localObjects: ResourceFinderType { get } from Resource it works.

Alternatively, if you remove the Resource constraint from ResourceFinder, it will also run successfully.

I have reported the issue and you can track it via SR-1314

like image 136
Stuart Carnie Avatar answered Oct 12 '22 17:10

Stuart Carnie