Skip to content

Reject argument command call taking a block with more trailing arguments#3652

Merged
kddnewton merged 1 commit into
ruby:mainfrom
Earlopain:command-call-trailing-args
Sep 19, 2025
Merged

Reject argument command call taking a block with more trailing arguments#3652
kddnewton merged 1 commit into
ruby:mainfrom
Earlopain:command-call-trailing-args

Conversation

@Earlopain

Copy link
Copy Markdown
Collaborator

https://bugs.ruby-lang.org/issues/21168#note-5

The added code samples align with parse.y, except for foo(bar baz do end) which parse.y currently rejects but shouldn't.

@Earlopain
Earlopain force-pushed the command-call-trailing-args branch 2 times, most recently from d254970 to eff58a3 Compare September 17, 2025 15:24
@kddnewton

Copy link
Copy Markdown
Collaborator

I'm okay to merge this as-is, but I'm wondering if it indicates that we're passing accepts_command_call incorrectly somewhere or we're not checking it somewhere. Because this behavior should be controlled by that flag.

@Earlopain

Copy link
Copy Markdown
Collaborator Author

Let me check again later when I got some time. I didn't yet find the place where accepts_command_call would be relevant while making this PR

@Earlopain

Earlopain commented Sep 17, 2025

Copy link
Copy Markdown
Collaborator Author

Actually, would accepts_command_call be relevant? It doesn't reject commands calls but any argument after a command call (that takes a block).

@kddnewton

Copy link
Copy Markdown
Collaborator

I think so, because

prism/src/prism.c

Line 15584 in 90a098d

} else if (accepts_command_call && (token_begins_expression_p(parser->current.type) || match3(parser, PM_TOKEN_USTAR, PM_TOKEN_USTAR_STAR, PM_TOKEN_UAMPERSAND)) && !match1(parser, PM_TOKEN_BRACE_LEFT)) {
rejects any arguments without parentheses, which is what we're trying to reject here.

https://bugs.ruby-lang.org/issues/21168#note-5

The added code samples align with `parse.y`, except for `foo(bar baz do end)` which `parse.y` currently rejects but shouldn't.
@Earlopain
Earlopain force-pushed the command-call-trailing-args branch from eff58a3 to 3a4e102 Compare September 17, 2025 17:54
@Earlopain

Copy link
Copy Markdown
Collaborator Author

(I just rebased and added foo(bar 1 do end,) as a syntax error test)

That accepts_command_call just decides if bar 1 do end should be allowed. parse_arguments_list gets called twice:

foo(bar 1 do end, 2)
    ^~~~~~~~~~~~~~~ # accepts_command_call is irrelevant, parens are present
        ^~~~~~~~    # accepts_command_call is true. Having it be false would reject the first argument to `foo`, which should be allowed.

Though it's not unreasonable to think that I am missing something or that the fix is better placed at a different location

@kddnewton

Copy link
Copy Markdown
Collaborator

Right, but I'm talking about the bar method call, which would have been called from here:

prism/src/prism.c

Line 18647 in 90a098d

if (parse_arguments_list(parser, &arguments, true, accepts_command_call, (uint16_t) (depth + 1))) {
.

@Earlopain

Copy link
Copy Markdown
Collaborator Author

Yeah, but that command call is allowed. Only stuff following it should be rejected, so I don't currently see how it would be relevant.

It's ok to reject this if you want to take this yourself. Looking at the proper solution to learn from later is good for me too, I have stared at this for a while longer now and am not really getting any further.

@kddnewton

Copy link
Copy Markdown
Collaborator

Ahh I'm sorry, I misread the ticket. I think this is definitely correct.

@kddnewton
kddnewton merged commit 20e36fa into ruby:main Sep 19, 2025
60 checks passed
@Earlopain
Earlopain deleted the command-call-trailing-args branch October 3, 2025 10:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants