-
-
Notifications
You must be signed in to change notification settings - Fork 415
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
ponyc segfaults when trying to match using a single element tuple form #4412
Comments
At minimum, we want to display an error message, not have the compiler segfault. Running this with a debug version of the compiler to get a backtrace would be a good first step. We discussed during sync and a change to 1 tuple type is a big change and not one that we are interested in taking on but an RFC could be opened for it to discuss in more depth and minds could be changed. Even if we were inclined towards the change, this would still require an RFC. |
Is the In any case, I'll start looking into this. I imagined the 1-tuple change would be a much larger ask. There isn't a deep need for it currently. I may revisit the idea of an RFC once I have more Pony experience. I appreciate that it was discussed. Thanks! |
Here's a stacktrace:
Line 891 in genoperator.c appears to be returning "junk", but not NULL which would be "ok". Next steps is to debug what is going on in the genexpr call. LLVMValueRef l_value = gen_expr(c, left); Once we know what is going on, I think we can discuss the correct fix. |
The issue seems to be an extra
ponyc/src/libponyc/codegen/genmatch.c Lines 318 to 329 in 46eb348
The generated AST of the problematic match looks like this:
A pseudo trace of what is happening that leads to the crash is as follows:
Changing this to a loop in for(int i = 0; pattern_child != NULL; i++)
{
pony_assert(ast_id(pattern_child) == TK_SEQ);
// Skip over the SEQ nodes
ast_t* pattern_expr = ast_child(pattern_child);
while(ast_id(pattern_expr) == TK_SEQ)
{
pony_assert(ast_childcount(pattern_expr) == 1);
pattern_expr = ast_child(pattern_expr);
}
if(!dynamic_tuple_element(c, ptr, desc, pattern_expr, next_block, i))
return false;
pattern_child = ast_sibling(pattern_child);
} I noticed this same ponyc/src/libponyc/codegen/genoperator.c Lines 435 to 442 in 46eb348
I imagine this could occur elsewhere if unexpected nested |
@jemc I think you know this code better than I. Do you have anything to contribute here? If we don't have any feedback for you by next week @chriskdon I'll dig into this, but I wouldn't have time to early October. |
No rush at all, @SeanTAllen. Thanks for taking a look. I'm happy to take this in whatever the preferred direction is. |
ponyc
segfaults when trying to usematch
with a single element tuple destructure form. As expected, it works when you don't use the tuple syntax in the match and with multi-element tuples.Use Case:
I understand that using a single-element tuple is strange since it's effectively the same as a standalone value. Still, in my use case, I had some code like:
type Term is ((Tuple, (Value)) | (Tuple, (Value, Value)) | (Tuple, (Value, Value, Value)) | ...)
, where I wanted to support a few small tuple sizes for convenience in serialization code.(Value)
being a tuple is ambiguous, I can see the compiler doesn't treat it as such since it doesn't generate an_1
member.I can work around this using the non-tuple syntax in the match, but it's nice to have the match look the same as the type.
Minimal Example
Expected Result:
The compiler doesn't crash.
I would expect this syntax to be allowed in a
match
because(let y: I32) = (I32(100))
(assignment destructure) is valid and works.Actual Result:
Environment
Compiler
Also failed in
0.55.0
I'm guessing this has something to do with 1-element tuples not "really" being tuples, and the
match
isn't taking this into account like the regular assignment destructure. This is a guess; I still need to dig into the compiler code.If there is some direction on the actual expected behaviour of the
match
, I'm happy to try and fix this myself. If you have any suggestions on where to begin in the code, it's always appreciated.As an aside:
Because
(MyType)
doesn't generate a 1-tuple as might be expected, it may be worth having the compiler emit an error or warning if the(MyType)
syntax is used when defining a type and the extra parens are not required (like when defining a union). This could help to avoid confusion. I didn't think about the(MyType)
syntax not generating a tuple until I ran into other syntax errors likecouldn't find _1
. I assume this case can be detected unambiguously, but I could be totally wrong here, so please forgive my ignorance.Alternatively, I would like it even more if this created a real 1-tuple for consistency. But I'm guessing there are reasons it doesn't.
The text was updated successfully, but these errors were encountered: