Skip to content

fix(parser): repeated ( / parenthesis / opened sub-expressions causes memory leak#16204

Merged
Bahex merged 2 commits intonushell:mainfrom
Bahex:subexpr-perf-fix
Jul 21, 2025
Merged

fix(parser): repeated ( / parenthesis / opened sub-expressions causes memory leak#16204
Bahex merged 2 commits intonushell:mainfrom
Bahex:subexpr-perf-fix

Conversation

@Bahex
Copy link
Copy Markdown
Member

@Bahex Bahex commented Jul 18, 2025

Description

Don't attempt further parsing when there is no complete sub-expression.

@github-actions github-actions bot added the A:parser Issues related to parsing label Jul 18, 2025
@Bahex Bahex requested a review from sholderbach July 19, 2025 17:02
@Bahex Bahex added the notes:fixes Include the release notes summary in the "Bug fixes" section label Jul 20, 2025
Copy link
Copy Markdown
Contributor

@WindSoilder WindSoilder left a comment

Choose a reason for hiding this comment

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

Thanks! LGTM

@Bahex Bahex merged commit 30c38b8 into nushell:main Jul 21, 2025
16 checks passed
@github-actions github-actions bot added this to the v0.106.0 milestone Jul 21, 2025
Comment on lines -2006 to -2011
.iter()
.any(|e| match e {
ParseError::Unclosed(right, _) if right == ")" => true,
ParseError::Unbalanced(left, right, _) if left == "(" && right == ")" => true,
_ => false,
});
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Looking back at this, do we need the change to .first().is_some_and() from .any() at all?

If the first error is one of the paren related ones (expanded back in #16235) it will short circuit the same. If there is another error in the given span that is handled by parse_paren_expr it would also stop trying if there is a balancing error following. Would that be more tolerant?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

If one of these errors appear after any other error, it means the outer expression was parsed successfully but actually parsing its content raised another error before raising one of these two.
In that case, attempting to parse the expression as a bare word interpolation wouldn't make sense.

if malformed_subexpr {
working_set.parse_errors.truncate(starting_error_count);
parse_string(working_set, span)
parse_string_interpolation(working_set, span)
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Can you explain this particular change?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

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

Any bare word expression that's passed to parse_paren_expr always includes a sub-expression, so parse_string would call parse_string_interpolation with any input it could be called with here.
I'm not sure why I initially implemented it with parse_string in the first place, but that contributed to deep call stack problem this PR solves. Calling parse_string_interpolation should make what happens here a little more clear while avoiding an unnecessary call.


let expr = parse_full_cell_path(working_set, None, span);
output.push(expr);
if delimiter_stack.is_empty() {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Making this conditional makes intuitive sense to me :D

hardfau1t pushed a commit to hardfau1t/nushell that referenced this pull request Aug 25, 2025
…es memory leak (nushell#16204)

- fixes nushell#16186

# Description

Don't attempt further parsing when there is no complete sub-expression.

---------

Co-authored-by: Bahex <17417311+Bahex@users.noreply.github.com>
@Bahex Bahex deleted the subexpr-perf-fix branch March 22, 2026 12:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A:parser Issues related to parsing notes:fixes Include the release notes summary in the "Bug fixes" section

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Parsing repeated ( / opened subexpressions goes OOM

3 participants