Hey, I'm getting this error: Segmentation fault: 11
and I'm hoping to get some insight on to resolve it or if it's a compiler bug. The below code is from John Sundell's site, it worked fine in Swift 4, but it crashes when attempting to build this code using Swift 5. I've updated the Result
type to use the one included in the new Standard Lib, which is the only change I've made it. My existing project returns the Segmentation fault: 11
error and complains about this line init(_ value: NewValue? = nil)
in the Promise class.
To test, simply create a new project, create a new file and stick this the code below. The examples projects fail to compile, they just sit.
class Future<Value> {
fileprivate var result: Result<Value, Error>? {
didSet { result.map(report) }
}
private lazy var callbacks = [(Result<Value, Error>) -> Void]()
func observe(with completion: @escaping (Result<Value, Error>) -> Void) {
callbacks.append(completion)
result.map(completion)
}
private func report(result: Result<Value, Error>) {
callbacks.forEach({ $0(result) })
}
@discardableResult
func transform<NextValue>(_ callback: @escaping (Value) throws -> NextValue) -> Future<NextValue> {
return chain({ (value) -> Future<NextValue> in
return try Promise(callback(value))
})
}
@discardableResult
func chain<NextValue>(_ closure: @escaping (Value) throws -> Future<NextValue>) -> Future<NextValue> {
let promise = Promise<NextValue>()
observe { (result) in
switch result {
case .success(let value):
do {
// Attempt to construct a new future given
// the value from the first one
let future = try closure(value)
// Observe the "nested" future, and once it
// completes, resolve/reject the "wrapper" future
future.observe(with: { result in
switch result {
case .success(let value):
promise.resolve(with: value)
case .failure(let error):
promise.reject(with: error)
}
})
} catch {
promise.reject(with: error)
}
case .failure(let error):
promise.reject(with: error)
}
}
return promise
}
}
class Promise<NewValue>: Future<NewValue> {
init(_ value: NewValue? = nil) {
super.init()
result = value.map(Result.success)
}
func resolve(with value: NewValue) {
result = .success(value)
}
func reject(with error: Error) {
result = .failure(error)
}
}
Any idea what going on?