-
-
Notifications
You must be signed in to change notification settings - Fork 1.8k
Flakes: provide robust access to outPath through new meta argument
#8908
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
base: master
Are you sure you want to change the base?
Changes from all commits
dfe4fa9
2d235db
d10bc47
4e3890d
e9e1897
2cf4b75
ab6dbf3
1f739ff
72675eb
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2750,6 +2750,109 @@ static RegisterPrimOp primop_catAttrs({ | |
| .fun = prim_catAttrs, | ||
| }); | ||
|
|
||
| static void prim_functionStrict(EvalState & state, const PosIdx pos, Value * * args, Value & v) | ||
| { | ||
| state.forceValue(*args[0], pos); | ||
| if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) { | ||
| v.mkNull(); | ||
| return; | ||
| } | ||
|
|
||
| state.forceFunction(*args[0], pos, "while evaluating the argument passed to builtins.functionStrict"); | ||
| const auto fun = args[0]->lambda.fun; | ||
|
|
||
| if (args[0]->isLambda() && fun->hasFormals()) { | ||
| v.mkBool(true); | ||
| } else { | ||
| v.mkNull(); | ||
| } | ||
| } | ||
|
|
||
| static RegisterPrimOp primop_functionStrict({ | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This should be Additionally, not all functions that are strict in their argument have formals, as the documentation also admits, e.g.: foo: builtins.seq foo (/* body … */)
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I couldn't care less about the syntax of a function, which is why I've named these primops after the semantics. By calling it has formals we can't go back and add a syntax to make functions with formals lazy. What matters is that the function definition is trivially strict, so that's what the name reflects. Should it be If this function is too contentious, I might remove it because it turned out that this one wasn't necessary for the use case I'm trying to solve. I think it's good to have, but low impact, so I don't want to waste time on it.
This is for improving error messages in a few cases, and nothing more.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Well the semantics are fundamentally not introspectable, so the naming is very deceptive.
It wouldn't really matter, the introspection would still do its job as advertised—there would be a breaking change in the semantics of the language, but that would be a problem regardless of the existence of that builtin. |
||
| .name = "__functionStrict", | ||
| .args = {"f"}, | ||
| .doc = R"( | ||
| Return `true` if *f* is a function that is defined using strict function | ||
| syntax, which is to say, using an argument attribute set declaration such | ||
| as `{ a }:` or `{ ... }:`. | ||
|
|
||
| Proper strictness analysis is undecidable, so for all other functions the | ||
| return value is `null`. `false` is not returned. | ||
| )", | ||
| .fun = prim_functionStrict, | ||
| }); | ||
|
|
||
| static void prim_functionOpen(EvalState & state, const PosIdx pos, Value * * args, Value & v) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Open is new terminology that has not appeared so far, as far as I am aware. I'd stick to something with ellipsis which is also terminology used by |
||
| { | ||
| state.forceValue(*args[0], pos); | ||
| if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) { | ||
| v.mkNull(); | ||
| return; | ||
| } | ||
|
|
||
| state.forceFunction(*args[0], pos, "while evaluating the argument passed to builtins.functionOpen"); | ||
| const auto fun = args[0]->lambda.fun; | ||
|
|
||
| if (args[0]->isLambda()) { | ||
| v.mkNull(); | ||
| } | ||
|
|
||
| if (fun->hasFormals()) { | ||
| v.mkBool(fun->formals->ellipsis); | ||
| } else { | ||
| v.mkNull(); | ||
| } | ||
| } | ||
|
|
||
| static RegisterPrimOp primop_functionOpen({ | ||
| .name = "__functionOpen", | ||
| .args = {"f"}, | ||
| .doc = R"( | ||
| Return `true` if *f* is a function that is defined using the ellipsis syntax, such as `{ ... }:` or `{ foo, ... }:`. | ||
|
|
||
| Return `false` for functions defined with an attribute list but no ellipsis, such as `{ foo, bar }:`. | ||
|
|
||
| Return `null` for functions defined using plain lambdas, such as `x: ...`, as well as for built-in functions. | ||
| )", | ||
| .fun = prim_functionOpen, | ||
| }); | ||
|
|
||
| static void prim_functionBindsAllAttrs(EvalState & state, const PosIdx pos, Value * * args, Value & v) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What is this needed for? I don't really see an use case for this right away.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's used in this PR to report a warning when a flake's The lack of ellipsis means that we'd have to remove the attribute for compatibility, while
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not just check for an ellipsis (functionOpen)? Whether the user also binds the whole attribute set, is not really interesting for that.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. If it has ellipsis, but no binding for the whole attrset, there's no conflict and the backcompat logic can comply with the old interface and it doesn't have to warn about anything. I don't want it to warn about something that isn't a problem, because too many warnings lead people to ignore them.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, but why not just warn if it lacks an ellipsis. The full attribute set binding should be irrelevant.
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
The ambiguity of #8908 (comment) does not occur if the full attrset binding is missing. So to keep warnings to a minimum, I want to know whether the full attrset binding exists or not. I can agree that it should but unfortunately it would require me to warn in cases where it doesn't matter. |
||
| { | ||
| state.forceValue(*args[0], pos); | ||
| if (args[0]->isPrimOpApp() || args[0]->isPrimOp()) { | ||
| v.mkNull(); | ||
| return; | ||
| } | ||
|
|
||
| state.forceFunction(*args[0], pos, "while evaluating the argument passed to builtins.functionBindsAllAttrs"); | ||
| const auto fun = args[0]->lambda.fun; | ||
|
|
||
| if (!args[0]->isLambda()) { | ||
| v.mkNull(); | ||
| return; | ||
| } | ||
|
|
||
| if (fun->hasFormals()) { | ||
| v.mkBool(fun->arg != Symbol {}); | ||
| } else { | ||
| v.mkNull(); | ||
| } | ||
| } | ||
|
|
||
| static RegisterPrimOp primop_functionBindsAllAttrs({ | ||
| .name = "__functionBindsAllAttrs", | ||
| .args = {"f"}, | ||
| .doc = R"( | ||
| If the function is not defined with an argument list, return `null`. | ||
|
|
||
| Return `true` if *f* is a function that is defined using the `@` syntax, which binds an identifier to the original attribute set. | ||
|
|
||
| Return `false` for a function that does not use the `@` syntax. | ||
| )", | ||
| .fun = prim_functionBindsAllAttrs, | ||
| }); | ||
|
|
||
| static void prim_functionArgs(EvalState & state, const PosIdx pos, Value * * args, Value & v) | ||
| { | ||
| state.forceValue(*args[0], pos); | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.