3

So I'm trying to understand generic protocols and classes:

protocol ListPresenterType where View.PDO.SW == Dispatcher.SW {
    associatedtype Dispatcher: ListDispatcherType
    associatedtype View: ListViewType

    init(dispatcher: Dispatcher, state: @escaping (_ state: AppState)->(ListState<Dispatcher.SW>))

    func attachView(_ view: View)
    ...
}

And I'm initiating it from another generic class:

class AbstractListViewController<Presenter: ListPresenterType, PDO: ListPDOCommonType, ...>: ListViewType, ... where PDO.SW == Presenter.Dispatcher.SW, ... {
    func configure(withBla: bla) {
        ...
        presenter = Presenter(dispatcher: dispatcher, state: state)
    }

    func someFunc() {
        presenter.attachView(self) // ERROR: Cannot invoke 'attachView' with an argument list of type ...
}

As I understand, I'm trying to initialize a type conforming to a generic protocol, which works just fine, but the type of View must be inconsistent with what I'm trying to feed it in attachView(:).

Then I try to initialize it with concrete view, changing init:

init(dispatcher: Dispatcher, view: View, state: @escaping (_ state: AppState)->(ListState<Dispatcher.SW>)) { 
    self.view = view 
    ... 
}

And in AbstractListViewController:

presenter = Presenter(dispatcher: dispatcher, view: self, state: state)

And getting this infamous error:

Non-nominal type 'Presenter' does not support explicit initialization

Here're gists with relevant playgrounds:

  1. Successful init (though cannot invoke attachView(:)) https://gist.github.com/nikans/0fde838846ffa9ff2da48c923f850625
  2. Init failing with aforementioned error: https://gist.github.com/nikans/53c3ea146ceb12dc8461f7ba8a81793d

Please notice that every empty protocol there is in fact a generic protocol, I've just removed the unnecessary details.


I'd like to understand:

  1. What makes a "nominal" type "non-nominal" all of a sudden (nothing to be surprised of, it's a generic parameter conforming to a generic protocol, but I don't understand the causation).
  2. I heard something about type erasure, but didn't quite get if it is applicable here.

Thanks.

nikans
  • 2,468
  • 1
  • 28
  • 35
  • Instead of showing snippets of code with no context, could you show enough actual detail to allow someone else to reproduce? – matt Sep 07 '17 at 01:45
  • Good idea, but because of all objects being generic and depending on types of every other it'd probably be either a lot of code or not enough details still. I'll try to create a playground. – nikans Sep 07 '17 at 01:52
  • UPD: I've added the gists with minimal reproducible code – nikans Sep 07 '17 at 02:18
  • Hmm. Does Swift version matter? In your "Init failing with aforementioned error", what I get is `cannot invoke initializer for type 'Presenter' with an argument list of type ... expected an argument list of type '(dispatcher: Self.Dispatcher, view: Self.View)'` and `cannot invoke 'attachView' with an argument list of type ... expected an argument list of type '(Presenter.View)'` – matt Sep 07 '17 at 02:52
  • I use swift 3 but compile with xcode 9 beta 6. This whole thing just doesn't work in xcode 8, dunno about the playgrounds. I'll check. – nikans Sep 07 '17 at 07:52
  • True, xcode8 returns `Cannot invoke initializer for type 'Presenter' with an argument list of type '(dispatcher: Presenter.Dispatcher!, view: AbstractListViewController)'`, so basically some types are not resolved correctly for some reason. Maybe some constraints are not there. – nikans Sep 07 '17 at 15:58
  • The only constraint I can think of is something like `Presenter.View == Self`, but that does not compile (obviously?). It says, `Expected an argument list of type '(dispatcher: Self.Dispatcher, view: Self.View)'` – nikans Sep 07 '17 at 16:02

1 Answers1

3

So it appears that in Xcode9 (beta 6) errors like Non-nominal type '%type' does not support explicit initialization simply equals the mismatching types error in less buggy Xcode (if that's a thing): cannot invoke initializer for type '%type' with an argument list of type '...' expected an argument list of type '...'

nikans
  • 2,468
  • 1
  • 28
  • 35