swiftlang / swift

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

[SR-1978] Crash on tuple splat with empty tuple / no arguments #44587

Closed swift-ci closed 8 years ago

swift-ci commented 8 years ago
Previous ID SR-1978
Radar None
Original Reporter VladimirS (JIRA User)
Type Bug
Status Resolved
Resolution Done
Environment Swift Ver. 3.0 (Jun 20, 2016) Target: x86_64-ubuntu-linux-gnu
Additional Detail from JIRA | | | |------------------|-----------------| |Votes | 0 | |Component/s | Compiler | |Labels | Bug, CompilerCrash | |Assignee | None | |Priority | Medium | md5: 189cf980068cef07ae4c82023ef41ee8

Issue Description:

let f: () -> Void = { x in print(x) }
let z : Void = ()
f(z)
Unhandled conversion from exploded tuple
UNREACHABLE executed at /home/buildnode/jenkins/workspace/oss-swift-package-linux-ubuntu-15_10/swift/lib/SILGen/SILGenPoly.cpp:879!
0  swift           0x00000000032f4138 llvm::sys::PrintStackTrace(llvm::raw_ostream&) + 40
1  swift           0x00000000032f2936 llvm::sys::RunSignalHandlers() + 54
2  swift           0x00000000032f4c66
3  libpthread.so.0 0x00007f14791f7d10
4  libc.so.6       0x00007f1477b3f1c7 gsignal + 55
5  libc.so.6       0x00007f1477b40e2a abort + 362
6  swift           0x00000000032a1c6d llvm::llvm_unreachable_internal(char const*, char const*, unsigned int) + 461
7  swift           0x00000000009b814d
8  swift           0x00000000009c0de5
9  swift           0x00000000009b4203
10 swift           0x00000000009b3afc
11 swift           0x000000000098c74e
12 swift           0x0000000000980f1d
13 swift           0x00000000009710b9
14 swift           0x000000000097119d
15 swift           0x0000000000934d4e
16 swift           0x000000000093564b
17 swift           0x0000000000936352 swift::SILModule::constructSIL(swift::ModuleDecl*, swift::SILOptions&, swift::FileUnit*, llvm::Optional<unsigned int>, bool, bool) + 482
18 swift           0x00000000009368e6 swift::performSILGeneration(swift::FileUnit&, swift::SILOptions&, llvm::Optional<unsigned int>, bool) + 118
19 swift           0x00000000007d96ff
20 swift           0x00000000007d56f1 swift::performFrontend(llvm::ArrayRef<char const*>, char const*, void*, swift::FrontendObserver*) + 2833
21 swift           0x00000000007a26cb main + 2603
22 libc.so.6       0x00007f1477b2aac0 __libc_start_main + 240
23 swift           0x00000000007a0249 _start + 41
Stack dump:
0.  Program arguments: /usr/bin/swift -frontend -c -primary-file /swift-execution/Sources/main.swift -target x86_64-unknown-linux-gnu -disable-objc-interop -I /swift-execution/.build/debug -enable-testing -g -module-cache-path /swift-execution/.build/debug/ModuleCache -D SWIFT_PACKAGE -emit-module-doc-path /swift-execution/.build/debug/TempCode.build/main~partial.swiftdoc -Onone -module-name TempCode -emit-module-path /swift-execution/.build/debug/TempCode.build/main~partial.swiftmodule -emit-dependencies-path /swift-execution/.build/debug/TempCode.build/main.d -emit-reference-dependencies-path /swift-execution/.build/debug/TempCode.build/main.swiftdeps -num-threads 8 -o /swift-execution/.build/debug/TempCode.build/main.swift.o 
1.  While emitting reabstraction thunk in SIL function @_TTRXFo_iP___XFo___<unknown>:0: error: unable to execute command: Aborted
<unknown>:0: error: compile command failed due to signal (use -v to see invocation)
belkadan commented 8 years ago

This isn't legal any more, but clearly the compiler should reject it rather than crashing.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Could you clarify, why this is not legal any more?

Is it because of SE-0066 ? If so, please note that there is a discussion in swift evalution mail list if that proposal should disallow sending emtpy tuple () to func with empty list of parameters. (for example in "[Pre-proposal] Fix function type grammar" thread) with such comments:

"
> Right, there is some impact on existing code that was omitted
> in the proposal. And it wasn't considered during review. Awkward.

Probably because some(many?) people (like me) did not understand that this proposal is much bigger than "Just require parentheses on function types", because IMHO the major idea of this proposal was disallow `Int->Int` syntax but not to disallow void parameter for zero parameter functions.

I hope community will provide opinions regarding this issue and about the decision regarding the void parameter to argument-less functions, and if that decision is really expected and was clearly mentioned in the proposal.

Personally I think we need to implement the proposal in all areas except this one and raise new proposal to make all things clear regarding argument-less functions.
"

belkadan commented 8 years ago

No, it's SE-0029, which was accepted long before SE-0066.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Well.. Actually I thought that SE-0029 was implemented a long time ago, and as soon as we can write the following code currently in 3.0 (Jun 20, 2016), I thought that sending void(empty tuple) to function with empty param list is and will allowed as edge case :

let f: () -> Void = { _ in print("") }

let z : Void = ()

f(())

Actually I still believe in this and hope that the question regarding sending `()` to zero-parameters function should be discussed by the community and decided explicitely, as no one proposal(that I know of) mentions exactly this edge case.

Could you provide any official response to this subject?

belkadan commented 8 years ago

I'm not a core team member, but I consider that a bug, not a feature. Why would you want to do this, anyway?

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

I see. No, I believe this is not a bug but a feature that come from tuple-splat days and is useful in some cases of functional programming and working with generics, when you can pass result of `-> Void` function as argument to function defined as zero-parameters func or use Void as generic type and () as value to call zero-parameters func.

belkadan commented 8 years ago

I guess I should have phrased it as "when do you want to do this?" I believe this still works in the fully-generic case, but if the two-argument case doesn't work I don't see why the zero-argument case should.

belkadan commented 8 years ago

Do you have real-world code using this?

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Usually I used/saw this technique : you define a generic func/class with type T that accepts 'item' of type T and 'processor' for that item. Then, inside code of that generic func/class you call 'processor(item)'. Any func defined wihtout parameters now can accept () as argument, so your generic type code works in this case too - it sends () 'item' to processor() which is func with emtpy param list. Given that just func without parameters will not accept () as argument - you will need to wrap the function name with closure {_ in funcWithoutParams}. But probably there is other useful using of that feature.

swift-ci commented 8 years ago

Comment by Vladimir (JIRA)

Swift Ver. 3.0 (Aug 30, 2016), Platform: Linux (x86_64) - the initial code specified in the issue is compiling and working well.
will wait for SE-0110 implementation ;-)