swiftlang / swift

The Swift Programming Language
https://swift.org
Apache License 2.0
67.57k stars 10.35k forks source link

[SR-12134] Not enough simple delegation of generic type. #54569

Open swift-ci opened 4 years ago

swift-ci commented 4 years ago
Previous ID SR-12134
Radar rdar://problem/59216638
Original Reporter rsbw (JIRA User)
Type Improvement

Attachment: Download

Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | | |Labels | Improvement | |Assignee | None | |Priority | Medium | md5: 5da667e3486520c170e5ec6a1bef9e08

Issue Description:

Simple case:

    func value<T>() -> T? {
        switch T.self {
        case is Data.Type: break
        case is String.Type: break
        case is [[String: Any?]].Type: break
        default: break
        }
        return nil
    }

    func required<T>() throws -> T {
        if let value = self.value() as? T {     // <- error
            return value
        }
        throw NSError(domain: "", code: 1000)
    }

Generic parameter 'T' could not be inferred

beccadax commented 4 years ago

@swift-ci create

hborla commented 4 years ago

This will compile if you use coercion instead of a conditional cast:

if let value = self.value() as T? {

A conditional cast x as? T happens at runtime, so the type checker doesn't use the type that you're casting to when inferring the type of x - it has to be able to infer the type of x independently.

Coercion is the way to specify a generic argument when the type parameter is the return type of the generic function.

hborla commented 4 years ago

This is really subtle though, and the diagnostic can definitely be improved!