nix-shell: restore backwards-compat with old nixpkgs#6664
nix-shell: restore backwards-compat with old nixpkgs#6664thufschmitt merged 2 commits intoNixOS:masterfrom
Conversation
Basically an attempt to resume fixing NixOS#5543 for a breakage introduced earlier[1]. Basically, when evaluating an older `nixpkgs` with `nix-shell` the following error occurs: λ ma27 [~] → nix-shell -I nixpkgs=channel:nixos-18.03 -p nix error: anonymous function at /nix/store/zakqwc529rb6xcj8pwixjsxscvlx9fbi-source/pkgs/top-level/default.nix:20:1 called with unexpected argument 'inNixShell' at /nix/store/zakqwc529rb6xcj8pwixjsxscvlx9fbi-source/pkgs/top-level/impure.nix:82:1: 81| 82| import ./. (builtins.removeAttrs args [ "system" "platform" ] // { | ^ 83| inherit config overlays crossSystem; This is a problem because one of the main selling points of Nix is that you can evaluate any old Nix expression and still get the same result (which also means that it *still evaluates*). In fact we're deprecating, but not removing a lot of stuff for that reason such as unquoted URLs[2] or `builtins.toPath`. However this property was essentially thrown away here. The change is rather simple: check if `inNixShell` is specified in the formals of an auto-called function. This means that { inNixShell ? false }: builtins.trace inNixShell (with import <nixpkgs> { }; makeShell { name = "foo"; }) will show `trace: true` while args@{ ... }: builtins.trace args.inNixShell (with import <nixpkgs> { }; makeShell { name = "foo"; }) will throw the following error: error: attribute 'inNixShell' missing This is explicitly needed because the function in `pkgs/top-level/impure.nix` of e.g. NixOS 18.03 has an ellipsis[3], but passes the attribute-set on to another lambda with formals that doesn't have an ellipsis anymore (hence the error from above). This was perhaps a mistake, but we can't fix it anymore. This also means that there's AFAICS no proper way to check if the attr-set that's passed to the Nix code via `EvalState::autoCallFunction` is eventually passed to a lambda with formals where `inNixShell` is missing. However, this fix comes with a certain price. Essentially every `shell.nix` that assumes `inNixShell` to be passed to the formals even without explicitly specifying it would break with this[4]. However I think that this is ugly, but preferable: * Nix 2.3 was declared stable by NixOS up until recently (well, it still is as long as 21.11 is alive), so most people might not have even noticed that feature. * We're talking about a way shorter time-span with this change being in the wild, so the fallout should be smaller IMHO. [1] NixOS@9d612c3 [2] NixOS/rfcs#45 (comment) [3] https://github.com/NixOS/nixpkgs/blob/release-18.03/pkgs/top-level/impure.nix#L75 [4] See e.g. the second expression in this commit-message or the changes for `tests/ca/nix-shell.sh`.
a41f22d to
98946e2
Compare
|
We're still recovering from the 2.4 shock, aren't we. Tbh, I don't think anyone cares about |
In the sense that they're using it. Not in the sense that this broke old evals. And do take it with a grain of salt. It's out in the wild now... |
|
Yep, I think that this is the least problematic solution to the problem IMHO. What do @edolstra and @thufschmitt think? :) |
thufschmitt
left a comment
There was a problem hiding this comment.
What do @edolstra and @thufschmitt think? :)
That it's a very dirty hack 🙃 But it's probably the best we can do.
It's a shame that this fix is itself breaking backwards-compat (although in a more limited fashion), but again, I don't think we can do better.
|
@thufschmitt fixed :) |
|
@edolstra wdyt? :) |
Basically an attempt to resume fixing #5543 for a breakage introduced
earlier[1]. Basically, when evaluating an older
nixpkgswithnix-shellthe following error occurs:This is a problem because one of the main selling points of Nix is that
you can evaluate any old Nix expression and still get the same result
(which also means that it still evaluates). In fact we're deprecating,
but not removing a lot of stuff for that reason such as unquoted URLs[2]
or
builtins.toPath. However this property was essentially thrown awayhere.
The change is rather simple: check if
inNixShellis specified in theformals of an auto-called function. This means that
will show
trace: truewhilewill throw the following error:
This is explicitly needed because the function in
pkgs/top-level/impure.nixof e.g. NixOS 18.03 has an ellipsis[3], butpasses the attribute-set on to another lambda with formals that doesn't
have an ellipsis anymore (hence the error from above). This was perhaps
a mistake, but we can't fix it anymore. This also means that there's
AFAICS no proper way to check if the attr-set that's passed to the Nix
code via
EvalState::autoCallFunctionis eventually passed to a lambdawith formals where
inNixShellis missing.However, this fix comes with a certain price. Essentially every
shell.nixthat assumesinNixShellto be passed to the formals evenwithout explicitly specifying it would break with this[4]. However I think
that this is ugly, but preferable:
Nix 2.3 was declared stable by NixOS up until recently (well, it still
is as long as 21.11 is alive), so most people might not have even
noticed that feature.
We're talking about a way shorter time-span with this change being
in the wild, so the fallout should be smaller IMHO.
[1] 9d612c3
[2] NixOS/rfcs#45 (comment)
[3] https://github.com/NixOS/nixpkgs/blob/release-18.03/pkgs/top-level/impure.nix#L75
[4] See e.g. the second expression in this commit-message or the changes
for
tests/ca/nix-shell.sh.cc @andir @edolstra @thufschmitt @Ericson2314 @roberth