Skip to content
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-75] Referencing a protocol function crashes the compiler #42697

Closed
swift-ci opened this issue Dec 5, 2015 · 8 comments
Closed

[SR-75] Referencing a protocol function crashes the compiler #42697

swift-ci opened this issue Dec 5, 2015 · 8 comments

Comments

@swift-ci
Copy link
Collaborator

swift-ci commented Dec 5, 2015

Previous ID SR-75
Radar rdar://21289579
Original Reporter Sephiroth87 (JIRA User)
Type Bug
Status Resolved
Resolution Done

Attachment: Download

Environment

Xcode 7.1.1

Additional Detail from JIRA
Votes 4
Component/s Compiler
Labels Bug, CompilerCrash
Assignee @slavapestov
Priority Medium

md5: 85007b8954c0d9c1507fbd1a12838bdf

is duplicated by:

  • SR-2544 Compiler crash on access to protocol function
  • SR-3036 Crash When Calling Curried Instance Method on Protocol
  • SR-3670 Calling default implementation as a curried method causes compiler crash
  • SR-4375 Using Generic with Protocols causes Segmentation Fault
  • SR-5638 Compiler Crash - Protocol Function Reference
  • SR-6234 Compiler crashes with protocol P { func f() }; type(of: P.f)
  • SR-7264 Compile-time segmentation fault while referencing protocol method
  • SR-7633 Compiler crash (Segmentation Fault 11) when assigning protocol method to variable
  • SR-7968 Compiler crash when accessing protocol extension method by type name
  • SR-8654 Trying to get Protocol.method crashes the compiler
  • SR-8904 Compiler crash when using protocol function as member of protocol.
  • SR-9053 Compiler crashes with Segmentation fault
  • SR-9147 Compiler crash in lowering
  • SR-9779 Crash while emitting SIL for curried call to protocol instance method
  • SR-10345 Compiler crash on invalid closure syntax
  • SR-10618 Trying to get a reference to a protocol's member crashes the compiler
  • SR-10815 Protocol method partial application seg fault
  • SR-11769 Crash when attempting to assign an unbound method from a protocol
  • SR-12589 Segmentation Fault when compiling instance method call from protocol
  • SR-12604 Crash creating unbound reference to protocol method
  • SR-12657 Swift 5.2 compiler crash, protocol method reference
  • SR-5240 Creating a reference to a protocol-based function crashes the compiler

relates to:

  • SR-1329 LLVM error when assigning protocol function to variable

Issue Description:

The following code will crash the compiler

protocol MyProtocol {
    func myFunc() -> String
}

let f = MyProtocol.myFunc
@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 8, 2015

Comment by Arthur Sabintsev (JIRA)

You're not supposed to call functions directly on a protocol. A class conforms to the protocol and implements the method.
Depending on if the function is static function or an instance method (in your example, it's the latter), you can call the function on the class or instance of the class.

I think your point was that the compiler is crashing due to this, and rather an error should be thrown, which is the case if you do something like:

protocol MyProtocol {
    static func MyFunc() -> String
}

let f = MyProtocol.MyFunc // error: static member 'MyFunc' cannot be used on instance of type 'MyProtocol.Protocol'

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 8, 2015

Comment by Fabio Ritrovato (JIRA)

That's exactly my point 🙂

@swift-ci
Copy link
Collaborator Author

swift-ci commented Dec 8, 2015

Comment by Arthur Sabintsev (JIRA)

Got it. Nice find! 🙂

@slavapestov
Copy link
Member

slavapestov commented Dec 17, 2015

We plan on making MyProtocol.someInstanceMethod work. You can already do this for classes, eg,

class Foo {
func f() { ... }
}

let f: Foo -> () -> () = Foo.f

It should have the same behavior for protocols:

protocol Foo {
func f()
}

let f: Foo -> () -> () = Foo.f

I plan on addressing this later.

@swift-ci
Copy link
Collaborator Author

swift-ci commented Jun 16, 2017

Comment by Jeremy Lew (JIRA)

@slavapestov This has been hanging around for a while, do you know if it's on any roadmap?

@swift-ci
Copy link
Collaborator Author

swift-ci commented Aug 7, 2017

Comment by Justin Guedes (JIRA)

@slavapestov Any update on this bug? 🙂

@swift-ci
Copy link
Collaborator Author

swift-ci commented Aug 29, 2018

Comment by Greg Omelaenko (JIRA)

Just wondering, how is

let f = MyProtocol.myFunc

different from

let f = { (x: MyProtocol) in x.myFunc }

? I understand this won't work if MyProtocol has an associatedtype, but it seems like this kind of expression can't reasonably work for those cases anyway. Am I missing something?

@slavapestov
Copy link
Member

slavapestov commented Feb 26, 2020

grego (JIRA User) in fact you've hit the nail on the head; the two forms are equivalent, and the compiler should be able to handle the first just as it can handle the second.

The problem here is that partially-applied method references were emitted using a different code path than normal closures. I'm working on a change to convert these forms into ordinary closures in the type checker, which fixes various odd cases that were not supported (such as this one) and allows simplifying a lot of code in other parts of the compiler.

I've got a WIP PR up: #28698

@swift-ci swift-ci transferred this issue from apple/swift-issues Apr 25, 2022
This issue was closed.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants