Swift: Spurious type mismatch calling generic function with protocol-conforming struct's dynamic type

Originator:twiomood
Number:rdar://21936501 Date Originated:21-Jul-2015 11:34 PM
Status:Open Resolved:
Product:Developer Tools Product Version:Xcode 7.0 b4
Classification:Other Bug Reproducible:Always
 
Summary:
A generic function that is declared to take a value that conforms to a protocol and the Type of the same protocol fails to take said arguments.
If I pass in a concrete struct that conforms, and that struct's dynamicType, no error is emitted.

Steps to Reproduce:
Compile the attached sample with Xcode 7.0 beta 4:

xcrun -sdk macosx swiftc -c struct-conforming-protocol-dynamic-type-as-type-argument.swift


Expected Results:
Seems like it should compile *or* it should fail in the case that `value` is typed as Value instead of ValueProtocol.


Actual Results:
The to() function fails to match the passed arguments, with the errors

struct-conforming-protocol-dynamic-type-as-type-argument.swift:34:1: error: cannot invoke 'to' with an argument list of type '(ValueProtocol, t: ValueProtocol.Type)'
to(value, t:value.dynamicType)
^
struct-conforming-protocol-dynamic-type-as-type-argument.swift:34:1: note: expected an argument list of type '(T, t: T.Type)'
to(value, t:value.dynamicType)
^

but this seems like they do match with T=ValueProtocol.


Version:
Xcode 7.0 b4

Notes:


Configuration:


Attachments:

/*

xcrun -sdk macosx swiftc -c struct-conforming-protocol-dynamic-type-as-type-argument.swift

This results in errors, even though the second argument is supposed to be of ValueProtocol.Type. If `value` is not typed to ValueProtocol (so it is inferred as Value), then no error is emitted.

struct-conforming-protocol-dynamic-type-as-type-argument.swift:34:1: error: cannot invoke 'to' with an argument list of type '(ValueProtocol, t: ValueProtocol.Type)'
to(value, t:value.dynamicType)
^
struct-conforming-protocol-dynamic-type-as-type-argument.swift:34:1: note: expected an argument list of type '(T, t: T.Type)'
to(value, t:value.dynamicType)
^

*/

public protocol ValueProtocol {
    var value:Double { get }
    init(_ value:Double)
}

public struct Value : ValueProtocol {
    public let value:Double
    public init(_ value:Double) {
        self.value = value
    }
}

public func to<T:ValueProtocol>(x:T, t: T.Type) -> T {
    return t.init(x.value)
}

let value:ValueProtocol = Value(10)

to(value, t:value.dynamicType)

Comments

Why not just declare func to be like this:

public func to(x:T) -> T { return T.init(x.value) }

and call it like this:

let v = to(value)


Please note: Reports posted here will not necessarily be seen by Apple. All problems should be submitted at bugreport.apple.com before they are posted here. Please only post information for Radars that you have filed yourself, and please do not include Apple confidential information in your posts. Thank you!