libexpr/primops: make break force its argument
previously, `builtins.break` didn't force its argument, resulting in a value wrapped with `break` being opaque to most builtins if not also wrapped with `seq`. see [lix-project/lix#1165] for more details on what this can break. this tiny fix just adds a call to `forceValue` inside `prim_break`, but unfortunately this "breaks" a few existing tests because it changes the call stack; those tests' golden outputs have been adjusted without modifying their intended purpose. Fixes #1165 [lix-project/lix#1165]: https://git.lix.systems/lix-project/lix/issues/1165 Change-Id: I5fe4ee3ff28b38aaf924125b8978130812e58fef
This commit is contained in:
@@ -27,3 +27,59 @@ def test_debugger_output(nix: Nix):
|
||||
assert "error: oh snap" in res.stderr_plain
|
||||
assert re.findall(r"with: .*a", res.stdout_plain)
|
||||
assert re.findall(r"static: .*x", res.stdout_plain)
|
||||
|
||||
|
||||
def test_transparent_break(nix: Nix):
|
||||
"""
|
||||
Make sure that adding a call to builtins.break doesn't
|
||||
change the result of an expression
|
||||
"""
|
||||
|
||||
expr = dedent("""
|
||||
let
|
||||
inherit (builtins)
|
||||
attrNames
|
||||
break
|
||||
elem
|
||||
functionArgs
|
||||
head
|
||||
isAttrs
|
||||
isPath
|
||||
isFunction
|
||||
map
|
||||
mapAttrs
|
||||
removeAttrs
|
||||
toJSON
|
||||
typeOf;
|
||||
in
|
||||
builtins.all (b: b) [
|
||||
((attrNames { a = 5; }) == (attrNames (break { a = 5; })))
|
||||
((elem 5 [1 5]) == (elem 5 (break [1 5])))
|
||||
((elem (2+3) [1 (2+3)]) == (elem (2+3) (break [1 (2+3)])))
|
||||
((functionArgs ({ a }: 5)) == (functionArgs (break ({ a }: 5))))
|
||||
((head [1 2]) == (head (break [1 2])))
|
||||
((isAttrs { a = 5; }) == (isAttrs (break { a = 5; })))
|
||||
((isPath ./.) == (isPath (break ./.)))
|
||||
((isPath ./${".meow"}) == (isPath (break ./${".meow"})))
|
||||
((isFunction (x: x)) == (isFunction (break (x: x))))
|
||||
((map (x: x) [1 5]) == (map (x: x) (break [1 5])))
|
||||
((mapAttrs (n: v: v) { a = 5; }) == (mapAttrs (n: v: v) (break { a = 5; })))
|
||||
((removeAttrs { a = 5; b = 6; } ["a"]) == (removeAttrs (break { a = 5; b = 6; }) ["a"]))
|
||||
((removeAttrs { ab = 5; } [("a"+"b")]) == (removeAttrs { ab = 5; } [(break ("a"+"b"))]))
|
||||
((toJSON { a = 5; }) == (toJSON (break { a = 5; })))
|
||||
((toJSON { a = [(1+2)]; }) == (toJSON { a = break [(1+2)]; }))
|
||||
((typeOf { a = 5; }) == (typeOf (break { a = 5; })))
|
||||
((typeOf (1+2)) == (typeOf (break (1+2))))
|
||||
]
|
||||
""")
|
||||
|
||||
res_no_dbg = nix.nix(["eval", "--expr", expr], flake=True).run().expect(0)
|
||||
assert "true" in res_no_dbg.stdout_plain
|
||||
|
||||
res_with_dbg = (
|
||||
nix.nix(["eval", "--debugger", "--expr", expr], flake=True)
|
||||
.with_stdin(b":c\n" * 50)
|
||||
.run()
|
||||
.expect(0)
|
||||
)
|
||||
assert "true" in res_with_dbg.stdout_plain
|
||||
|
||||
Reference in New Issue
Block a user