New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
lib/attrsets: make toDerivation x always work when isStorePath x #119406
Conversation
A better fix would be to error out when a list is passed. This way you might slip in a list of numbers and get really confusing error message. |
This is already done by
The issue I'm fixing is only the edge case where you would pass a list like I'm not sure that it's necessarily a good thing you can pass lists here, but the impact is somewhat limited since the resulting coerced string needs to be of a certain form to type check. If we wanted to rewrite the type check however, we'd likely want to get rid of the string coercion, but this is a more sensitive thing to do than my fix, as you'd need to be careful not to break existing configurations. For reference, this is the definition of the Lines 330 to 337 in d01c15e
|
I think we should go the other direction: Make
|
Done! Opted for a very simple extra check. |
lib/attrsets.nix
Outdated
@@ -325,7 +325,7 @@ rec { | |||
/* Converts a store path to a fake derivation. */ | |||
toDerivation = path: | |||
let | |||
path' = builtins.storePath path; | |||
path' = builtins.storePath (toString path); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this still needed though? I wouldn't think so
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You're right, dropped that commit. It does everything we want (__toString
, derivations, strings, paths).
Since it checks if dirOf x is the nix store dir, a trailing slash will break this check and make it return false.
When a list is passed to isStorePath this is most likely a mistake and it is therefore better to just return false. There is one case where this theoretically makes sense (if a list contains a single element for which isStorePath elem), but since that case is also probably seldomly intentional, it may save someone from debbuging unclear evaluation errors.
14e9470
to
f39a5c4
Compare
Motivation for this change
isStorePath may be true for anything which
isCoercibleToString
, howeverthere seems to be different coercion behavior within nix builtins: a
list of derivations can be coerced to a string with
toString
, butbuiltins.storePath
will throw:This means that
lib.strings.isStorePath [ pkgs.hello ] == true
, butlib.toDerivation [ pkgs.hello ]
will throw. This causes very hard todebug evaluation errors when mistakenly putting a list in a place where
types.package
was expected since it expects to be able to calltoDerivation
on anything for thatisStorePath
returns true. Theevaluation errors for this issue are terrible as the only identifiable
location points to
toDerivation
and no offending values are printedsince
types.package
doesn't actually treat this situation as a typeerror.
This is however fixed easily: Just call
toString
before passing thevalue to
builtins.storePath
, so that builtin receives the same valueisStorePath
does its checks on.Things done
sandbox
innix.conf
on non-NixOS linux)nix-shell -p nixpkgs-review --run "nixpkgs-review wip"
./result/bin/
)nix path-info -S
before and after)