Marshall White Marshall White - 1 month ago 17
Swift Question

Workaround for specific generic type parameter

The situation:

I have two protocols, one with a static method:

protocol DataSourceable {
static func getMoreData<T: DataAccepting>(someObject: T)
}

protocol DataAccepting {
func accept(data: [Any])
}
extension DataAccepting where Self: UIViewController { }


which compiles fine.

Once I define a class with a type parameter conforming to
DataSourceable
:

class SampleViewController<T: DataSourceable>: UIViewController {...}


I get a
Segmentation Fault: 11
and the compiler crashes.

0 swift 0x0000000112445b6d PrintStackTraceSignalHandler(void*) + 45
1 swift 0x00000001124455b6 SignalHandler(int) + 470
2 libsystem_platform.dylib 0x00007fffa4bd9bba _sigtramp + 26
3 libsystem_platform.dylib 0x0000000000000002 _sigtramp + 1531077730
4 swift 0x000000010f8bd5bd swift::irgen::emitCategoryData(swift::irgen::IRGenModule&, swift::ExtensionDecl*) + 2285
5 swift 0x000000010f8c2425 swift::irgen::IRGenModule::emitGlobalDecl(swift::Decl*) + 1189
6 swift 0x000000010f8c1e85 swift::irgen::IRGenModule::emitSourceFile(swift::SourceFile&, unsigned int) + 133
7 swift 0x000000010f98dfe2 performIRGeneration(swift::IRGenOptions&, swift::ModuleDecl*, swift::SILModule*, llvm::StringRef, llvm::LLVMContext&, swift::SourceFile*, unsigned int) + 1282
8 swift 0x000000010f85c1c7 performCompile(swift::CompilerInstance&, swift::CompilerInvocation&, llvm::ArrayRef<char const*>, int&, swift::FrontendObserver*) + 23687
9 swift 0x000000010f854265 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 17029
10 swift 0x000000010f81182d main + 8685
11 libdyld.dylib 0x00007fffa49cd255 start + 1
12 libdyld.dylib 0x00000000000000c6 start + 1533226610
**More_Stuff**...
While emitting IR for source file /xx/xx/xx/xx/xx/xx/xx/SampleViewController.swift


The end goal is to be able to do this:

class SampleViewController<T: DataSourceable>: UIViewController, DataAccepting {
var intArray = [Int]()
func setup() {
T.getMoreData(dataAcceptor: self)
}

func accept(data: [Any]) {
intArray = data
}
}

struct SampleModel: DataSourceable {
static func getMoreData<T: DataAccepting>(dataAcceptor: T) {
var anIntArray = [Int]()
someObject.accept(anIntArray)
}
}


And then make a
SampleViewController<SampleModel>
.
This will allow me to let the SampleModel deal with sourcing data for the controller. The SampleModel decides how to get the data, then using the accept() function on the controller it can give the data to the SampleController.

Answer

This seems to be a compiler bug. However, you should avoid this design in general, as we discussed in chat.

Comments