It gives a warning on the lazy-trees branch of Nix
(NixOS/nix#6530)
one of these was also giving me an error (the one in lib/trivial probably)
```
$ nix build
warning: applying 'toString' to path '/home/artturin/nixgits/my-nixpkgs/nixos/modules/installer/sd-card/sd
-image-aarch64.nix' and then accessing it is deprecated, at /home/artturin/nixgits/my-nixpkgs/lib/modules.
nix:349:99
warning: applying 'toString' to path '/home/artturin/nixgits/my-nixpkgs/.git' and then accessing it is dep
recated, at /home/artturin/nixgits/my-nixpkgs/lib/sources.nix:35:32
warning: applying 'toString' to path '/home/artturin/nixgits/my-nixpkgs/nixos/modules/system/etc/etc.nix'
and then accessing it is deprecated, at «stdin»:0
warning: applying 'toString' to path '/home/artturin/nixgits/my-nixpkgs/nixos/modules/system/etc/etc-activ
ation.nix' and then accessing it is deprecated, at «stdin»:0
warning: applying 'toString' to path '/home/artturin/nixgits/my-nixpkgs/nixos/modules/installer/sd-card/sd
-image-aarch64.nix' and then accessing it is deprecated, at «stdin»:0
error: cannot decode virtual path '/nix/store/virtual0000000000000000000000005-source'
(use '--show-trace' to show detailed location information)
```
The code of `lib.closePropagation` was internally using a
recursion on the dependencies and returns all the derivation directly or
indirectly referenced by buildInputs.
`lib.closeProgation` is implemented in pure nix and uses an unique
function for list which is quadratic and does "true" equality, which
needs deep set comparison.
Instead, we use the `builtins.genericClosure` which is implemented as a
builtin and uses a more efficient sorting feature.
Note that `genericClosure` needs a `key` to discriminate the values, we
used the `outPath` which is unique and orderable.
On benchmarks, it performs up to 15x time faster on a benchmark related
to haskellPackages.ghcWithPackages.
Personally, I think that warnings such as
warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers..enable'.
are fairly confusing because of the `..` and it's more correct to
actually quote that. With this change the warning now looks like this:
warning: The option `services.redis.enable' defined in `/home/ma27/Projects/nixpkgs/test.nix@node-vm' has been renamed to `services.redis.servers."".enable'.
While implementing that I realized that you'd have
a similar problem whenever you use attribute-names that aren't
identifiers, e.g.
services.nginx.virtualHosts."example.org".locations."/".invalid = 23;
now results in the following error:
error: The option `interactive.nodes.vm.services.nginx.virtualHosts."example.org".locations."/".invalid' does not exist. Definition values:
- In `/home/ma27/Projects/nixpkgs/test.nix@node-vm': 23
Of course there are some corner-cases where this won't work: when
generating the manual, you display submodules like this:
services.nginx.virtualHosts.<name>
Since `<name>` isn't a value, but an indicator for a submodule, it must
not be quoted. This also applies to the following identifiers:
* `*` for `listOf submodule`
* `<function body>` for `functionTo`
This might not be correct if you actually have a submodule with an
attribute name called `<name>`, but I think it's an improvement over the
current situation and for this you'd probably need to make even more
complex changes to the module system.
The motivation is to have a single identifier for that. Useful for the
next commit where I'll try to escape option-parts correctly (options can
be any kind of strings, but unless these are Nix identifiers, they must
be quoted).
Since `<function body>` (or `<name>`/`*`) are special identifiers in
error messages and the manual, we need a unique way to mark an option
part as function call because these are not to be quoted.