Fix panic on too few arguments for custom function#10395
Fix panic on too few arguments for custom function#10395WindSoilder merged 6 commits intonushell:mainfrom
Conversation
|
If the changes in error message for missing arguments before keywords is controversial, I can remove/extract it to a separate PR, since the actual fix to the crash is just the first commit with a single line changed + added tests. |
amtoine
left a comment
There was a problem hiding this comment.
not an expert on the parser at all, but from what i'm seeing in the tests and the PR description
- the bug appears to be fixed
- tests look good
- i think we can live without this cursed
alias = = =😆
thanks for tackling the parser @anka-213 🙏
|
Is there anything (other than the merge conflict in the tests) that is preventing this fix from being merged? |
WindSoilder
left a comment
There was a problem hiding this comment.
Hi, really thank you for the pr.
I'm sorry that it takes too much time to review it. I left a single question, and some comment.
|
|
||
| let positionals_between = kw_pos - positional_idx - 1; | ||
| if positionals_between > (kw_idx - spans_idx) { | ||
| if positionals_between >= (kw_idx - spans_idx) { |
There was a problem hiding this comment.
I should have documented it when I wrote this change, as I don't remember. 😅
The commit this change comes from says:
Handle multiple missing args before a keyword
calculate_end_span should only return spans_idx when the current
span is a keyword, but we require more positional before the keyword
But I'll have to think a bit more to remember why that meant that we want >=. I should've also added another testcase for that specific change, since it's a separate fix from the previous ones.
There was a problem hiding this comment.
Yeah I have the question because I tried something like let = 3 without this change, it also reports new error message.
There was a problem hiding this comment.
Yeah, I unfortunately still don't remember. I believe I had some reason for it, but it was a year ago and I didn't write enough down. I tried changing it to panic on == and running the fuzzer to see when the equals case would happen with no success. My commit message unfortunately wasn't clear enough for me to understand it, since I no longer remember how the parser works.
I would be fine with either reverting that change or keeping it. The test cases succeed in both cases, so it only makes a difference in some untested case (if ever).
The case of equality did trigger in a few tests, but for all of those, positionals_between was equal to 0, which means that the result of the two variants are identical.
It could be the case that the change only matters if there is a command with more than one required argument before a keyword argument, which there are currently none. But after trying out adding such a command, those seem to be broken enough to not even trigger this code path at all (I should ensure that there is no regression for that in this patch, even though no such command currently exist). That turned out to just be an issue with special-casing of the keyword "let". I should've tried a custom keyword instead.
There was a problem hiding this comment.
Ah ok. Thank you for the detailed information. If you believe you had some reason for it, I think we can keep it.
It could be the case that the change only matters if there is a command with more than one required argument before a keyword argument, which there are currently none. But after trying out adding such a command, those seem to be broken enough to not even trigger this code path at all (I should ensure that there is no regression for that in this patch, even though no such command currently exist).
Yeah I believe the parser had been changed a lot from the pr you created before. So it might be checked and broken elsewhere.
|
This PR could be split into two PRs. one for the two first commits (the second commit is just a refactoring on top of the first). and another for the final two commits. I don't know if that would've made reviewing easier? (but the later changes depend on the earlier, so this was the easiest for me) |
Old code was comparing remaining positional arguments with total number of arguments, where it should've compared remaining positional with with remaining arguments of any kind Fixes nushell#9072
All the branching can be reduced to saturated subtraction
calculate_end_span should only return spans_idx when the current span is a keyword, but we require more positional before the keyword
I think it's ok to be one PR. One is because the new error message seems fine to me, and the change is small enough, I can review them together. |
WindSoilder
left a comment
There was a problem hiding this comment.
Really appreciate for the pr! It looks good to me :-)
Description
Old code was comparing remaining positional arguments with total number
of arguments, where it should've compared remaining positional with
with remaining arguments of any kind. This means that if a function was given too few arguments,
calculate_end_spanwould believe that it actually had too many arguments, since after parsing the first few arguments, the number of remaining arguments needed were fewer than the total number of arguments, of which we had used several.Fixes #9072
Fixes: #13930
Fixes: #12069
Fixes: #8385
Extracted from #10381
Bonus
It also improves the error handling on missing positional arguments before keywords (no longer crashing since #9851). Instead of just giving the keyword to the parser for the missing positional, we give an explicit error about a missing positional argument. I would like better descriptions than "missing var_name" though, but I'm not sure if that's available without
Old error
New error
User-Facing Changes
The program
alias = = =is no longer accepted by the parserTests + Formatting
Make sure you've run and fixed any issues with these commands:
cargo fmt --all -- --checkto check standard code formatting (cargo fmt --allapplies these changes)cargo clippy --workspace -- -D warnings -D clippy::unwrap_usedto check that you're using the standard code stylecargo test --workspaceto check that all tests pass (on Windows make sure to enable developer mode)cargo run -- -c "use std testing; testing run-tests --path crates/nu-std"to run the tests for the standard library-->
After Submitting