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-1261] Swift incorrectly identifies passing a tuple to a function as a tuple splat #43869
Comments
cc cwillmore (JIRA User), though note that Dave mentioned he'd be interested in learning about the issue and possibly taking it on himself. |
Comment by David Sweeris (JIRA) I'm quite interested, but everything I know about compilers is a vague recollection about BNF and YACC from some class I took over a decade ago, so I won't be able to fix it today or anything. Edit: More precisely, I don't even know how long it'll be before I'd know enough to give an ETA, so I don't know if that works with how y'all schedule stuff. |
Comment by David Sweeris (JIRA) I'm finally gotten a chance to dive into this a bit. I think I know where the bug is (or at least where it’s manifesting itself), but I haven't figured out how to fix it yet. In the function `void checkTupleSplat(ApplyExpr *Call)`, in MiscDiagnostics.cpp (which starts on line 388, at least in the version I'm using), the diagnostic message is triggered when `(TT -> getNumElements() > 1)`, rather than when the # of elements passed in isn't the same as the # that's expected. I believe the preceding line (395) is intended to solve the problem by just returning early if `arg` (which is equal to `Call->getArg()->getSemanticsProvidingExpr()`) is a `TupleExpr`, `TupleShuffleExpr`, or one of a couple other non-tuple-related things. In any case, I think the root bug is that `isa<TupleExpr>(arg) || isa<TupleShuffleExpr>(arg)` is returning false when it should be returning true. I’m currently investigating what values of x in `isa<x>(arg)` will come back as true. I’m hoping that it's something related to typealiases, because it seems that the likely problem would then be that compiler just isn’t peeling back the onion enough, so to speak, which seems like an easy fix. |
Backslashes escape formatting characters in JIRA. I don't think it's a typealias thing. That would affect the Type of the Expr but not the Expr itself. What's more likely is that, as a single-arg no-label argument list, it's being treated as a ParenExpr…which normally would be a tuple splat. My guess is there's nothing currently trying to distinguish these cases: |
Comment by David Sweeris (JIRA) Yeah, `isa<ParenExpr>(Call->getArg())` returns true. And thanks for the JIRA tip. I should probably read the manual or something :-) |
Comment by David Sweeris (JIRA) Oh![]( I've found a work-around) If you put the tuple in an extra set of parens, like class BinaryOp<A1, A2, R> : Op<((A1, A2)), R> {//class def} then the problem goes away. I think that means the bug is maybe in the specializer? |
Comment by David Sweeris (JIRA) In the RefinedNotASplat.swift file, I duplicate some functionality between two sets of classes, one with typealiases declared as late as possible (which works as expected) and the other declaring them as early as possible (which requires the extra set of parens around the generic tuple in the inheritance clause in order to work). I'm still trying to pin down exactly where the compiler goes wrong. |
Comment by David Sweeris (JIRA) I think this might be related to the ambiguity Joe Groff noted in this message regarding SE-0066: Standardize function type argument syntax to require parentheses. |
Comment by David Sweeris (JIRA) I need to amend my earlier claim that the "problem goes away" if you use an extra set of parens. The "workaround" does prevent the compiler from complaining about tuple splats, but if you try to actually compile the code in question, the compiler crashes with a segfault: 11 error |
Comment by David Sweeris (JIRA) It seems to depend on where the overloaded function is declared. I've uploaded "CompilesOK.swift" and "CrashesCompiler.swift" to illustrate the difference. |
Swift on master has a better implementation of SE-0110 than Swift 3, where it was completely broken. It looks like the NotASplat and RefinedNotASplat examples now typecheck on master, but CrashesCompiler.swift still crashes. I'll take a look. |
... and the testcase now passes on master. I'll add it as a regression test. |
Attachment: Download
Environment
Xcode 7.3 (7D175), OS X 10.11.4, Mac Pro 2008
Additional Detail from JIRA
md5: 6f10fb16a9469ba513311d1018d6e633
relates to:
Issue Description:
In the Swift 2.2 toolchain distributed with Xcode 7.3, the compiler incorrectly flags a function which takes one argument of a generic type as "passing 2 arguments ... as a single tuple value" when the generic type is itself a tuple. The generic type in question is bounced around as generic parameters through class inheritance, so maybe that's part of the problem
I've attached a .swift file with the code needed to generate the warning.
FWIW, Jordan Rose thinks it might be "an issue with the diagnostic".
(https://lists.swift.org/pipermail/swift-dev/Week-of-Mon-20160418/001733.html)
The text was updated successfully, but these errors were encountered: