about summary refs log tree commit diff
path: root/tvix/eval/src/value/string.rs
diff options
context:
space:
mode:
authorAdam Joseph <adam@westernsemico.com>2023-09-09T06·38-0700
committerclbot <clbot@tvl.fyi>2023-09-15T00·00+0000
commit92566210097bf301e7f6651c161115a51598f20d (patch)
tree4bb119876e5214324b51203e2f18be8bd91cd159 /tvix/eval/src/value/string.rs
parent95ee688f0338a080b039de6e971bc91ba133a863 (diff)
fix(tvix/eval): update identifier quoting to match cppnix 2.17 r/6589
In cppnix 2.17, commit b72bc4a972fe568744d98b89d63adcd504cb586c, the
libexpr pretty-printing routine was fixed so that it would no longer
pretty-print attrsets with keywords in their attrnames incorrectly.

This commit implements the corresponding fix for tvix, fixes our
tests to work with cppnix>=2.17 oracles, and expands our test cases
to cover all the keywords.

Change-Id: I4b51389cd3a9c44babc8ab2a84b383b7b0b116ca
Reviewed-on: https://cl.tvl.fyi/c/depot/+/9283
Autosubmit: Adam Joseph <adam@westernsemico.com>
Reviewed-by: sterni <sternenseemann@systemli.org>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/value/string.rs')
-rw-r--r--tvix/eval/src/value/string.rs13
1 files changed, 12 insertions, 1 deletions
diff --git a/tvix/eval/src/value/string.rs b/tvix/eval/src/value/string.rs
index 2649e00f08..8ffbc2a532 100644
--- a/tvix/eval/src/value/string.rs
+++ b/tvix/eval/src/value/string.rs
@@ -135,7 +135,7 @@ impl NixString {
             // A borrowed string is unchanged and can be returned as
             // is.
             Cow::Borrowed(_) => {
-                if is_valid_nix_identifier(&escaped) {
+                if is_valid_nix_identifier(&escaped) && !is_keyword(&escaped) {
                     escaped
                 } else {
                     Cow::Owned(format!("\"{}\"", escaped))
@@ -171,6 +171,17 @@ fn nix_escape_char(ch: char, next: Option<&char>) -> Option<&'static str> {
     }
 }
 
+/// Return true if this string is a keyword -- character strings
+/// which lexically match the "identifier" production but are not
+/// parsed as identifiers.  See also cppnix commit
+/// b72bc4a972fe568744d98b89d63adcd504cb586c.
+fn is_keyword(s: &str) -> bool {
+    match s {
+        "if" | "then" | "else" | "assert" | "with" | "let" | "in" | "rec" | "inherit" => true,
+        _ => false,
+    }
+}
+
 /// Return true if this string can be used as an identifier in Nix.
 fn is_valid_nix_identifier(s: &str) -> bool {
     // adapted from rnix-parser's tokenizer.rs