about summary refs log tree commit diff
path: root/nix/yants
diff options
context:
space:
mode:
authorsterni <sternenseemann@systemli.org>2021-02-18T00·33+0100
committersterni <sternenseemann@systemli.org>2021-02-19T16·14+0000
commit690994a28cc3045c14268996144e9302fa43bf68 (patch)
tree54386d6fcb9f04ff1fb18f8be4b6477cdaa3e759 /nix/yants
parente628862e97acc5cd9aa2c9da86f26edd6d14605c (diff)
fix(nix/yants): make (typedef …).checkType return a result set r/2222
Previously, for types defined using typedef (like all primitive types)
type.checkType would return a boolean. This is largely fine since in
most places `type.checkToBool (type.checkType x)` or similar is used.
However, some functions actually take type.checkType up on the promise
that it returns a set of the form:

  {
    ok = <bool>;
    err = <option string>;
  }

This is the case for restrict which has checkToBool = v: v.ok; and will
generate a proper set except if `t.checkToBool (t.checkType v) == false`
in which case it will return t.checkType v. If t was a primitive type or
defined using typedef, previously `t.checkType v` would be a boolean
which meant as soon as (restrict …).checkToBool was called on a restrict
checkType result in cases where the wrapped type didn't match, an
unrelated error would be thrown:

  nix-repl> with nix.yants; restrict "foo" (_: true) int "lol"
  error: value is a boolean while a set was expected, at /home/lukas/src/depot/nix/yants/default.nix:38:39

This is fixed by making typedef return a proper set from checkType and
adjusting its checkToBool accordingly.

Unfortunately I don't think we can easily add test cases for this except
by using recursive nix or VM tests as there is no way to introspect
error messages.

Change-Id: I96a7be065630f04ca33358f21809284911ec14fe
Reviewed-on: https://cl.tvl.fyi/c/depot/+/2536
Tested-by: BuildkiteCI
Reviewed-by: tazjin <mail@tazj.in>
Reviewed-by: Profpatsch <mail@profpatsch.de>
Diffstat (limited to 'nix/yants')
-rw-r--r--nix/yants/default.nix10
1 files changed, 7 insertions, 3 deletions
diff --git a/nix/yants/default.nix b/nix/yants/default.nix
index 3e9a4c00a2..058444d27b 100644
--- a/nix/yants/default.nix
+++ b/nix/yants/default.nix
@@ -76,9 +76,13 @@ with builtins; let
   # error message constructor.
   typedef = name: check: typedef' {
     inherit name;
-    checkType = check;
-    checkToBool = r: r;
-    toError = value: _result: typeError name value;
+    checkType = v:
+      let res = check v;
+      in {
+        ok = res;
+      } // (lib.optionalAttrs (!res) {
+        err = typeError name v;
+      });
   };
 
   checkEach = name: t: l: foldl' (acc: e: