diff options
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.exp | 2 | ||||
-rw-r--r-- | tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.nix | 31 | ||||
-rw-r--r-- | tvix/eval/src/value/mod.rs | 19 |
3 files changed, 36 insertions, 16 deletions
diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.exp b/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.exp index a148ebc3b53f..cd5a6c0d5490 100644 --- a/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.exp +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.exp @@ -1 +1 @@ -[ "1" "4.200000" "" "" "1" "foo" "/etc" "Hello World" "Hello World" "1" "out" "2" "1 4.200000 1 foo /etc Hello World Hello World 1 out 2" ] +[ "" " " " /deep/thought" " 2 3" " flat" "1" "4.200000" "" "" "1" "foo" "/etc" "Hello World" "Hello World" "1" "out" "2" " /deep/thought 2 3 flat 1 4.200000 1 foo /etc Hello World Hello World 1 out 2" ] diff --git a/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.nix b/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.nix index e4dc18ac96a7..eb8011158fd0 100644 --- a/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.nix +++ b/tvix/eval/src/tests/tvix_tests/eval-okay-builtins-toString.nix @@ -5,19 +5,24 @@ let }; toStringExamples = [ - (toString 1) - (toString 4.2) - (toString null) - (toString false) - (toString true) - (toString "foo") - (toString /etc) - (toString toStringableSet) - (toString { __toString = _: toStringableSet; }) - (toString { __toString = _: true; }) - (toString { outPath = "out"; }) - (toString { outPath = { outPath = { __toString = _: 2; }; }; }) + null + [ null false ] + [ null /deep/thought ] + [ [ null 2 ] null 3 ] + [ false "flat" ] + 1 + 4.2 + null + false + true + "foo" + /etc + toStringableSet + { __toString = _: toStringableSet; } + { __toString = _: true; } + { outPath = "out"; } + { outPath = { outPath = { __toString = _: 2; }; }; } ]; in -toStringExamples ++ [ (toString toStringExamples) ] +(builtins.map toString toStringExamples) ++ [ (toString toStringExamples) ] diff --git a/tvix/eval/src/value/mod.rs b/tvix/eval/src/value/mod.rs index 0007735cc096..567a2f3df21b 100644 --- a/tvix/eval/src/value/mod.rs +++ b/tvix/eval/src/value/mod.rs @@ -315,6 +315,9 @@ impl Value { ) -> Result<Value, ErrorKind> { let mut result = String::new(); let mut vals = vec![self]; + // Track if we are coercing the first value of a list to correctly emit + // separating white spaces. + let mut is_list_head = None; loop { let value = if let Some(v) = vals.pop() { v.force(co, span.clone()).await? @@ -392,6 +395,12 @@ impl Value { for elem in list.into_iter().rev() { vals.push(elem); } + // In case we are coercing a list within a list we don't want + // to touch this. Since the algorithm is nonrecursive, the + // space would not have been created yet (due to continue). + if is_list_head.is_none() { + is_list_head = Some(true); + } continue; } @@ -419,9 +428,15 @@ impl Value { panic!("tvix bug: .coerce_to_string() called on internal value") } }; - if !result.is_empty() { - result.push(' '); + + if let Some(head) = is_list_head { + if !head { + result.push(' '); + } else { + is_list_head = Some(false); + } } + result.push_str(&coerced?); } } |