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

Treat untyped element in tuple and named tuple #6720

Conversation

makenowjust
Copy link
Contributor

Fixed #6718

The reason of #6718 is calling node.update with untyped TupleLiteral or NamedTupleLiteral. An untyped node has no node.program, so it fails nil assertion.

I think this node.update is not needed because CleanupTransformer does not change the type of node except for untyped and unreachable node. However such nodes should be transformed to other node. In other words node.update does nothing in general.

Thus, this replaces node.update with treating untyped element.

Copy link
Member

@asterite asterite left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think this is OK. What if some expressions inside the tuple are not untyped? Then, super should take care of handling untyped expressions. And then I can't see untyped expressions in the tests. I might give this a try and fix it.

@makenowjust
Copy link
Contributor Author

makenowjust commented Sep 14, 2018

Yes, there is no untyped expression in tests at least on cleanup phase after super called. It's important thing. (and I noted this as comment in spec.)

Maybe it is the simplest solution is moving node.update in behind of NoReturn processing and adding node.program = @program in front of node.update.
Perhaps it works fine. But, I'm wondering why this node.update is really needed.

@makenowjust
Copy link
Contributor Author

And, the above I commented is very conservative way.

@asterite
Copy link
Member

I don't understand, why is there a "Nil assertion failed"? Because @program is nil?

@straight-shoota
Copy link
Member

Because @program is nil?

Yes, looks like it.

@makenowjust
Copy link
Contributor Author

makenowjust commented Sep 14, 2018

Yes, @program is nil. It is not assigned a value to node.program (node is TupleLiteral or NamedTupleLiteral). This assignment is done in MainVisitor usually. However, in the test case, the block of pending is not processed by MainVisitor due to not invoked (pending has no yield), so the tuple literal inside block is untyped and its node.program is nil.

@asterite
Copy link
Member

I see.

Well, we have two solutions:

  1. Assign @program before calling node.update
  2. Remove @program altogether. It's needed to create a TupleType (program.tuple_type(...)) but we all Types have a reference to the Program, so we can simply do: program = elements.first.type inside TupleLiteral#update (after the first return unless...). Same goes for NamedTupleLiteral)

I much prefer the second option. It makes the code more robust (we don't need to remember to assign @program) and it makes TupleLiteral occupy less memory.

@makenowjust Would you like to do 2, or do you want me to do that?

@makenowjust
Copy link
Contributor Author

@asterite Removing node.program is good idea, but I don't know it works for an empty tuple and empty named tuple...

And it seems you are sure node.update is needed. But I'm unbelieving in it. Could you explain about this?

@asterite
Copy link
Member

@makenowjust Ah, right, I forgot about the empty case. Then yeah, let's set node.program = ... before calling node.update.

@straight-shoota
Copy link
Member

🏓

@straight-shoota
Copy link
Member

I'm a bit lost on how this should proceed... Who needs to take what action?

Fixed crystal-lang#6718

The reason of crystal-lang#6718 is calling `node.update` with untyped `TupleLiteral` or
`NamedTupleLiteral`. An untyped node has no `node.program`, so it fails nil
assertion.

I think this `node.update` is not needed because `CleanupTransformer`
does not change the type of `node` execpt for untyped and unreachable
node.  However such nodes should be transformed to other node.
In other words `node.update` does nothing in general.

Thus, this replaces `node.update` with treating untyped element.
…`CleanupTransformer`

And add assignment to `node.program` before it.

crystal-lang#6720 (comment)
@makenowjust makenowjust force-pushed the fix/crystal/6718-treat-untyped-expression-in-tuple branch from 0e03875 to 879977a Compare October 12, 2018 09:55
@makenowjust
Copy link
Contributor Author

Updated.

@bcardiff bcardiff added this to the 0.27.0 milestone Oct 12, 2018
def untyped(x = nil)
end

# To reproduce this bug, it is needed to the expression that is
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FYI the correct english is "... it is needed to have an expression that is ..." and it reads even better as "... it is required to have an expression that is ..."

@RX14 RX14 added kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler labels Oct 13, 2018
@RX14 RX14 merged commit 4528480 into crystal-lang:master Oct 13, 2018
@straight-shoota
Copy link
Member

Thanks @makenowjust !

@makenowjust makenowjust deleted the fix/crystal/6718-treat-untyped-expression-in-tuple branch October 26, 2018 07:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
kind:bug A bug in the code. Does not apply to documentation, specs, etc. topic:compiler
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants