about summary refs log tree commit diff
path: root/tvix/eval/src/errors.rs
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2022-09-13T13·37+0200
committersterni <sternenseemann@systemli.org>2022-09-15T11·47+0000
commitda1d71a4e8e3afee09d8f72b79b6042d4ccbfc2d (patch)
treefbe325478c5e818b824073fab3a2be98c0b1c26f /tvix/eval/src/errors.rs
parent16da548f93c9e8e9d4771240bb4a1bf14b9665aa (diff)
feat(tvix/eval): implement correct toString behavior r/4857
Implement C++ Nix's `EvalState::coerceToString` minus some of the Path
/ store handling. This is currently only used for `toString` which does
all possible coercions, but we've already prepared the weaker coercion
variant which is e.g. used for builtins that expect string arguments.

`EvalState::coerceToPath` is still missing for builtins that need a
path, but it'll be easy to build on top of this.

Change-Id: I78d15576b18921791d04b6b1e964b951fdef22c6
Reviewed-on: https://cl.tvl.fyi/c/depot/+/6571
Autosubmit: sterni <sternenseemann@systemli.org>
Reviewed-by: tazjin <tazjin@tvl.su>
Tested-by: BuildkiteCI
Diffstat (limited to 'tvix/eval/src/errors.rs')
-rw-r--r--tvix/eval/src/errors.rs23
1 files changed, 23 insertions, 0 deletions
diff --git a/tvix/eval/src/errors.rs b/tvix/eval/src/errors.rs
index 39b105de9812..086cc9d9052c 100644
--- a/tvix/eval/src/errors.rs
+++ b/tvix/eval/src/errors.rs
@@ -1,3 +1,4 @@
+use crate::value::CoercionKind;
 use std::fmt::Display;
 
 use codemap::{CodeMap, Span};
@@ -61,6 +62,12 @@ pub enum ErrorKind {
     /// chained up.
     ThunkForce(Box<Error>),
 
+    /// Given type can't be coerced to a string in the respective context
+    NotCoercibleToString {
+        from: &'static str,
+        kind: CoercionKind,
+    },
+
     /// Tvix internal warning for features triggered by users that are
     /// not actually implemented yet, and without which eval can not
     /// proceed.
@@ -158,6 +165,21 @@ to a missing value in the attribute set(s) included via `with`."#,
             // delegating to the inner error
             ErrorKind::ThunkForce(err) => err.message(codemap),
 
+            ErrorKind::NotCoercibleToString { kind, from } => {
+                let kindly = match kind {
+                    CoercionKind::Strong => "strongly",
+                    CoercionKind::Weak => "weakly",
+                };
+
+                let hint = if *from == "set" {
+                    ", missing a `__toString` or `outPath` attribute"
+                } else {
+                    ""
+                };
+
+                format!("cannot ({kindly}) coerce {from} to a string{hint}")
+            }
+
             ErrorKind::NotImplemented(feature) => {
                 format!("feature not yet implemented in Tvix: {}", feature)
             }
@@ -185,6 +207,7 @@ to a missing value in the attribute set(s) included via `with`."#,
             ErrorKind::ParseErrors(_) => "E015",
             ErrorKind::DuplicateAttrsKey { .. } => "E016",
             ErrorKind::ThunkForce(_) => "E017",
+            ErrorKind::NotCoercibleToString { .. } => "E018",
             ErrorKind::NotImplemented(_) => "E999",
         }
     }