nix icon indicating copy to clipboard operation
nix copied to clipboard

Multiple `with`s priority don't take into account if attributes exist

Open SuperSamus opened this issue 3 years ago • 1 comments

Describe the bug

An undocumented (from what I could find) feature of the with keyword, is that if multiple of them are used in the same expression, the last one will have priority:

nix-repl> with {a=1;}; with {a=2;}; a
2

Normally, if the attrsets have attributes with different names, the correct one is picked:

nix-repl> with {a=1;}; with {b=2;}; a
1

However, if the attributes are attrsets of the same name, and if the expression takes an attribute from that attrset, the expression tries to take it from the last attrset declared, even if it doesn't exist there.

nix-repl> with {a.foo=1;}; with {a.foo=2;}; a.foo
2

nix-repl> with {a=1;}; with {a.foo=2;}; a.foo     
2

nix-repl> with {a.foo=1;}; with {a=2;}; a.foo
error: value is an integer while a set was expected

       at «string»:1:31:

            1| with {a.foo=1;}; with {a=2;}; a.foo
             |                               ^

nix-env --version nix-env (Nix) 2.10.3

SuperSamus avatar Aug 03 '22 13:08 SuperSamus

This is correct behavior. In

with {a.foo=1;}; with {a=2;}; a.foo

the foo attribute does not exist in the a value that has precedence, therefore you get an error. Nix does not try to merge different variables with the same name in the lexical scope.

edolstra avatar Aug 03 '22 14:08 edolstra