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

parser: Remove empty multiline string parts earlier #11120

Merged
merged 2 commits into from
Jul 20, 2024

Conversation

infinisil
Copy link
Member

Motivation

Consider these two expressions:

# a.nix
[
  ''
    ${"string"}''
]
# b.nix
[
  ''${"string"}''
]

They parse differently:

$ nix-instantiate --parse a.nix
[ (("" + "string")) ]
$ nix-instantiate --parse b.nix
[ ("string") ]

The first one also ends up allocating an extra thunk to be evaluated, but they evaluate to the same:

$ NIX_SHOW_STATS=1 NIX_SHOW_STATS_PATH=stats.json nix-instantiate --eval --strict a.nix
[ "string" ]
$ jq .nrThunks stats.json
1

$ NIX_SHOW_STATS=1 NIX_SHOW_STATS_PATH=stats.json nix-instantiate --eval --strict b.nix
[ "string" ]
$ jq .nrThunks stats.json
0

There is no need for this inconsistency, so this PR changes it to treat both the same (a.nix now acts the same as b.nix). This is done by preventing the propagation of empty strings to be concatenated in the parser already.

Context

I've found this when I tried to verify that nix-instantiate --parse doesn't change upon applying a formatter on Nixpkgs. Turns out it does change at least because of this.

Priorities and Process

This work is sponsored by Antithesis

Add 👍 to pull requests you find important.

The Nix maintainer team uses a GitHub project board to schedule and track reviews.

@infinisil infinisil requested a review from edolstra as a code owner July 16, 2024 21:03
@github-actions github-actions bot added the with-tests Issues related to testing. PRs with tests have some priority label Jul 16, 2024
Copy link
Member

@roberth roberth left a comment

Choose a reason for hiding this comment

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

LGTM

tests/functional/lang/parse-okay-ind-string.exp Outdated Show resolved Hide resolved
@infinisil
Copy link
Member Author

Hold on, I think I found a minor problem with this, will follow-up

So that in the next commit we can see what changes about this test
Copy link
Member Author

@infinisil infinisil left a comment

Choose a reason for hiding this comment

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

Alright should be good now.

Comment on lines 303 to 310
/* If there is nothing at all, return the empty string directly */
if (es2->size() == 0) {
auto *const result = new ExprString("");
delete es2;
return result;
}

Copy link
Member Author

@infinisil infinisil Jul 17, 2024

Choose a reason for hiding this comment

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

The problem I discovered is fixed by this. This is necessary because newly es2 can be entirely empty, in which case we should not create an ExprConcatStrings, but just return an empty string directly. Not doing so would give inconsistent results from

''''

(which would newly create an ExprConcatStrings, allocating a thunk)

and

''
''

(which would be turned into "")

This is now covered in the test.

src/libexpr/parser-state.hh Outdated Show resolved Hide resolved
@roberth roberth added the language The Nix expression language; parser, interpreter, primops, evaluation, etc label Jul 17, 2024
Makes parsing more consistent and is a super minor optimisation

Co-authored-by: Robert Hensing <roberth@users.noreply.github.com>
@infinisil
Copy link
Member Author

Applied and rebased with your suggestion :)

@roberth roberth merged commit 584f8cb into NixOS:master Jul 20, 2024
11 checks passed
@infinisil infinisil deleted the early-string-cutoff branch July 21, 2024 01:22
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
language The Nix expression language; parser, interpreter, primops, evaluation, etc with-tests Issues related to testing. PRs with tests have some priority
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants