google / google/promises

Generic initialiser type mismatch causes crashes

Open
#177 1 comment 0 reactions 0 assignees View on GitHub
Dominant language
Objective-C
Stars
3.8k
Forks
316
PR merge metrics
No merged PRs in 30d

Description

## Problem

The following code compiles and causes a crash

```swift
let somePromise = Promise {
return Optional.none
}

somePromise.then { (v: String) in
// causes crash
print(v)
}
```

## Explanation

Here is a piece of code that causes this crash. The naming of the initialiser generic type `Value` can be easily confused with the class generic `Value` type, so I'll use two different names for my explanation below.

https://github.com/google/promises/blob/afa9a1ace74e116848d4f743599ab83e584ff8cb/Sources/Promises/Promise%2BDo.swift#L26-L38

The way the current convenience initialisers in Promise+Do.swift are written, they allow the user to create a promise of some type `OneValue` and pass a function that returns a type `SecondValue`. This is because the convenience initialisers contain their own generic type `SecondValue` which does not have the match the `OneValue` type of the class `Promise`. Since the generic type is erased to `ObjCPromise` when any class methods are run that cast the resolved to the class `OneValue` type

```swift
class Promise
convenience init(on queue: DispatchQueue = .promises, _ work: @escaping Do.__onQueue(queue) {
/*....*/
}
self.init(objCPromise)
objCPromise.__addPendingObject(self)
}
```

Is there any reason why there are generic initialiser types used in the project like these?

https://github.com/google/promises/blob/afa9a1ace74e116848d4f743599ab83e584ff8cb/Sources/Promises/Promise%2BDo.swift#L26

https://github.com/google/promises/blob/afa9a1ace74e116848d4f743599ab83e584ff8cb/Sources/Promises/Promise%2BDo.swift#L45

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.