New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[SR-1849] compilation crash for protocol with generic method #44458
Comments
I don't think we currently support this kind of constraint. @DougGregor, is that correct? |
This should be ill-formed. "bar" isn't actually a generic function. If we want this behavior, we should explicitly support it with "where" clauses on non-generic declarations. |
Comment by Vladimir (JIRA) So, do I understand this right, that the code above should not compile(even after crash is fixed) and for now we have no way to express such kind of protocol ? And, if this will be possible, the construction will be:
? And if so, this means that we should be able to do the following in any non-generic function: Should this be improved if existentials proposal gets approved and implemented in Swift 3+ ? |
The above code should not compile. I don't consider this to be part of the existentials proposal; I think it's a new feature of some sort. IIRC, the standard library has some use cases for this feature, where the Collection protocol would like to have a requirement like:: func index(of element: Element) -> Index? where Element : Equatable that's only a requirement when Element is Equatable. |
Comment by Vladimir (JIRA) Thank you for clarification. Do you think it's worth to be formed as a proposal for swift evolution? If so, what exactly feature should be proposed ? This ? :
I was hoping this can do the trick, but won't compile:
I got:
Any suggestions? |
As a side note, here's how stdlib Collection currently declares index(of element: Element) -> Index?:
I'm not sure I understand what the opportunities for improvements are for this current implementation and/or how it would benefit from some new feature. Either I'm misunderstanding everything here, or you just want something like this:
|
Comment by Vladimir (JIRA) Thank you for suggestion. But, as you most likely know, protocol extension methods if declared only in protocol extension (no in protocol definition itself)- will not be shadowed(overloaded) by the method in conforming type. Or I'm missing something. I.e. using your code, I want to be able to work with instance conformed to P protocol from inside a generic function. This is why I need a protocol for. Otherwise I can work in function with one concrete type name.
So, is there a method in Swift to implement my task ? Or we really need to propose the `func bar(t: T) where T : Equatable` syntax/feature ? |
Perhaps you already know all this and I'm missing your point: To get a function with test's signature to use S's bar, you'd have to check the type dynamically, like eg:
Or you could of course just write a couple of these:
It's hard to guess what a possibly simple solution could look like without knowing anything about the underlying task/problem. |
Comment by Vladimir (JIRA) Well, thank you, yes, I clearly understand why `S.bar` will not be called in `test` func in my code. Sorry, but your suggestion with explicit dynamic type checking and with function for specific type that implements the protocol - just not a solution. And, as I understand, I just have no way to make this in Swift currently. Actually, my task is really seems very close to what `index(of🙂` trying to achieve for Collection. func test<T: Collection where T.Iterator.Element == Int>(_ t: T) { It seems like right now I just have no way to implement my own Collection type with my custom `index(of🙂` that could be processed by that(or any other) generic func. Actually I understand "why", this is not the question : currently `index` is declared in protocol extension only. But, the question is if this is a wanted behavior and we actually don't need such feature : to be able to add constrains for associated type in particular methods in protocol. So, the proposal : allow additional constrains to be specified for specific method in protocol:
(In this case `index` is first class citizen just like any other method of protocol. It's implementation in type will be called in generic function.) Opinions? Other workarounds? (P.S. Sorry for my English) |
Comment by Vladimir (JIRA) Still error appears with Swift Ver. 3.0 (Aug 30, 2016), Platform: Linux (x86_64)
|
Comment by Vladimir (JIRA) I'm not about the correctness of the code, I'm about the compiler crash(as I understand) |
Current master compiles this. protocol P1 {
associatedtype T
func foo(t: T)
func bar<U>(t: U) where U == T, U: Equatable
}
struct S<T> : P1 {
func foo(t: T) {}
func bar<U: Equatable>(t: U) {
}
} That means, This works S<Int>().bar(t: 1) This is error (as expected) class C {}
S<C>().bar(t: C()) Here is the problem (no error): S<Int>().bar(t: 1.2 as Float)
|
That's correct behavior. When there's a concrete type, it doesn't go through the protocol at all, and the concrete type's implementation of |
That makes sense. Thank you! |
Environment
Swift Ver. 3.0 (Jun 6, 2016)
Target: x86_64-ubuntu-linux-gnu
Additional Detail from JIRA
md5: 26bdf3ed51603c4d1da662229f2d9e47
Issue Description:
When trying to compile this:
(should this compile at all?)
I got this error:
The text was updated successfully, but these errors were encountered: