swiftlang / swift

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

[SR-5952] Type checker rejects generic argument to Array.index(of:). #48511

Open swift-ci opened 7 years ago

swift-ci commented 7 years ago
Previous ID SR-5952
Radar None
Original Reporter gwk (JIRA User)
Type Bug
Environment $ swift --version Apple Swift version 4.0 (swiftlang-900.0.65 clang-900.0.37) Target: x86_64-apple-macosx10.9 $ uname -v Darwin Kernel Version 17.0.0: Thu Aug 24 22:01:05 PDT 2017; root:xnu-4570.1.46\~3/RELEASE_X86_64
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, DiagnosticsQoI, TypeChecker | |Assignee | @xedin | |Priority | Medium | md5: 44b14015fe1600464d2f0f75bc651fcb

Issue Description:

Examples (sorry for the bad formatting but JIRA is misbehaving - I tried):

struct S\<Element> {
var a: Array\<Element>
func f(element: Element) {
_= a.index(of: element)
}
}

func g\<T>(element: T, a: [T]) {
_= a.index(of: element)
}

Both of these examples give errors; I think they should compile!

tt.swift:5:11: error: cannot invoke 'index' with an argument list of type '(of: Element)'
_ = a.index(of: element)
^
tt.swift:5:11: note: expected an argument list of type '(of: Self.Element)'
_ = a.index(of: element)
^
tt.swift:10:9: error: cannot invoke 'index' with an argument list of type '(of: T)'
_ = a.index(of: element)
^
tt.swift:10:9: note: expected an argument list of type '(of: Self.Element)'
_ = a.index(of: element)
^

belkadan commented 7 years ago

The problem is that Element/T might not be Equatable, in which case you have no way to find out whether the elements actually match! But the error messages should actually say that, cc @xedin.

swift-ci commented 7 years ago

Comment by George King (JIRA)

Jordan, thank you for the help. I encountered this while trying to implement the Collection protocol on a generic struct that wraps Array. What happened was that I had not yet implemented `subscript`, but instead of saying that, the compiler complains `does not conform to protocol '_IndexableBase'`. At that moment, it suggested that I needed to implement `index(of🙂`; now when I try to reproduce it (I've since added some other stuff to my implementation) it says `note: protocol requires nested type 'SubSequence'; do you want to add it?`

I'm not sure what can be done but there are several areas for improvement I think. For starters, just look at the empty implementation `struct C\<Element>: Collection {}`. The messages do not lead the user in the right direction. `Sequence` is not mentioned at all, and `subscript` is only mentioned in the misleading _Indexable inference. The fact that the name `_IndexableBase` shows up in error messages at all is unfortunate; it looks like the public type alias `IndexableBase` was deprecated so this is totally inscrutable.

Thanks again!