Skip to content

Commit 80068f9

Browse files
committed
restore proper handling of no formals vs. 0 formals
e.g. (foo@{}: 1) { a = 3; } should error, but wasn't with the previous commit
1 parent 632767b commit 80068f9

File tree

9 files changed

+16
-18
lines changed

9 files changed

+16
-18
lines changed

src/libexpr-tests/primops.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ TEST_F(PrimOpTest, derivation)
771771
ASSERT_EQ(v.type(), nFunction);
772772
ASSERT_TRUE(v.isLambda());
773773
ASSERT_NE(v.lambda().fun, nullptr);
774-
ASSERT_TRUE(v.lambda().fun->hasFormals());
774+
ASSERT_TRUE(v.lambda().fun->hasFormals);
775775
}
776776

777777
TEST_F(PrimOpTest, currentTime)

src/libexpr/eval.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1496,13 +1496,13 @@ void EvalState::callFunction(Value & fun, std::span<Value *> args, Value & vRes,
14961496

14971497
ExprLambda & lambda(*vCur.lambda().fun);
14981498

1499-
auto size = (!lambda.arg ? 0 : 1) + lambda.nFormals;
1499+
auto size = (!lambda.arg ? 0 : 1) + (lambda.hasFormals ? lambda.getFormals().size() : 0);
15001500
Env & env2(mem.allocEnv(size));
15011501
env2.up = vCur.lambda().env;
15021502

15031503
Displacement displ = 0;
15041504

1505-
if (!lambda.hasFormals())
1505+
if (!lambda.hasFormals)
15061506
env2.values[displ++] = args[0];
15071507
else {
15081508
try {
@@ -1747,7 +1747,7 @@ void EvalState::autoCallFunction(const Bindings & args, Value & fun, Value & res
17471747
}
17481748
}
17491749

1750-
if (!fun.isLambda() || !fun.lambda().fun->hasFormals()) {
1750+
if (!fun.isLambda() || !fun.lambda().fun->hasFormals) {
17511751
res = fun;
17521752
return;
17531753
}

src/libexpr/include/nix/expr/nixexpr.hh

Lines changed: 4 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,7 @@ struct ExprLambda : Expr
484484
Symbol arg;
485485

486486
bool ellipsis;
487+
bool hasFormals;
487488
uint16_t nFormals;
488489
Formal * formalsStart;
489490

@@ -495,6 +496,7 @@ struct ExprLambda : Expr
495496
: pos(pos)
496497
, arg(arg)
497498
, ellipsis(formals.ellipsis)
499+
, hasFormals(true)
498500
, nFormals(formals.formals.size())
499501
, formalsStart(alloc.allocate_object<Formal>(nFormals))
500502
, body(body)
@@ -505,7 +507,7 @@ struct ExprLambda : Expr
505507
ExprLambda(std::pmr::polymorphic_allocator<char> & alloc, PosIdx pos, Symbol arg, Expr * body)
506508
: pos(pos)
507509
, arg(arg)
508-
, nFormals(0)
510+
, hasFormals(false)
509511
, formalsStart(nullptr)
510512
, body(body) {};
511513

@@ -523,11 +525,6 @@ struct ExprLambda : Expr
523525
void setName(Symbol name) override;
524526
std::string showNamePos(const EvalState & state) const;
525527

526-
inline bool hasFormals() const
527-
{
528-
return nFormals > 0;
529-
}
530-
531528
std::vector<Formal> getFormalsLexicographic(const SymbolTable & symbols) const
532529
{
533530
std::vector<Formal> result(getFormals().begin(), getFormals().end());
@@ -545,6 +542,7 @@ struct ExprLambda : Expr
545542

546543
std::span<Formal> getFormals() const
547544
{
545+
assert(hasFormals);
548546
return {formalsStart, nFormals};
549547
}
550548

src/libexpr/nixexpr.cc

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -154,7 +154,7 @@ void ExprList::show(const SymbolTable & symbols, std::ostream & str) const
154154
void ExprLambda::show(const SymbolTable & symbols, std::ostream & str) const
155155
{
156156
str << "(";
157-
if (hasFormals()) {
157+
if (hasFormals) {
158158
str << "{ ";
159159
bool first = true;
160160
// the natural Symbol ordering is by creation time, which can lead to the
@@ -451,14 +451,14 @@ void ExprLambda::bindVars(EvalState & es, const std::shared_ptr<const StaticEnv>
451451
if (es.debugRepl)
452452
es.exprEnvs.insert(std::make_pair(this, env));
453453

454-
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, nFormals + (!arg ? 0 : 1));
454+
auto newEnv = std::make_shared<StaticEnv>(nullptr, env, (hasFormals ? getFormals().size() : 0) + (!arg ? 0 : 1));
455455

456456
Displacement displ = 0;
457457

458458
if (arg)
459459
newEnv->vars.emplace_back(arg, displ++);
460460

461-
if (hasFormals()) {
461+
if (hasFormals) {
462462
for (auto & i : getFormals())
463463
newEnv->vars.emplace_back(i.name, displ++);
464464

src/libexpr/primops.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3363,7 +3363,7 @@ static void prim_functionArgs(EvalState & state, const PosIdx pos, Value ** args
33633363
if (!args[0]->isLambda())
33643364
state.error<TypeError>("'functionArgs' requires a function").atPos(pos).debugThrow();
33653365

3366-
if (!args[0]->lambda().fun->hasFormals()) {
3366+
if (!args[0]->lambda().fun->hasFormals) {
33673367
v.mkAttrs(&Bindings::emptyBindings);
33683368
return;
33693369
}

src/libexpr/value-to-xml.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -145,7 +145,7 @@ static void printValueAsXML(
145145
posToXML(state, xmlAttrs, state.positions[v.lambda().fun->pos]);
146146
XMLOpenElement _(doc, "function", xmlAttrs);
147147

148-
if (v.lambda().fun->hasFormals()) {
148+
if (v.lambda().fun->hasFormals) {
149149
XMLAttrs attrs;
150150
if (v.lambda().fun->arg)
151151
attrs["name"] = state.symbols[v.lambda().fun->arg];

src/libflake/flake.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -281,7 +281,7 @@ static Flake readFlake(
281281
if (auto outputs = vInfo.attrs()->get(sOutputs)) {
282282
expectType(state, nFunction, *outputs->value, outputs->pos);
283283

284-
if (outputs->value->isLambda() && outputs->value->lambda().fun->hasFormals()) {
284+
if (outputs->value->isLambda() && outputs->value->lambda().fun->hasFormals) {
285285
for (auto & formal : outputs->value->lambda().fun->getFormals()) {
286286
if (formal.name != state.s.self)
287287
flake.inputs.emplace(

src/nix/flake.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -473,7 +473,7 @@ struct CmdFlakeCheck : FlakeCommand
473473
if (!v.isLambda()) {
474474
throw Error("overlay is not a function, but %s instead", showType(v));
475475
}
476-
if (v.lambda().fun->hasFormals() || !argHasName(v.lambda().fun->arg, "final"))
476+
if (v.lambda().fun->hasFormals || !argHasName(v.lambda().fun->arg, "final"))
477477
throw Error("overlay does not take an argument named 'final'");
478478
// FIXME: if we have a 'nixpkgs' input, use it to
479479
// evaluate the overlay.

src/nix/nix-build/nix-build.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ static void main_nix_build(int argc, char ** argv)
416416
return false;
417417
}
418418
bool add = false;
419-
if (v.type() == nFunction && v.lambda().fun->hasFormals()) {
419+
if (v.type() == nFunction && v.lambda().fun->hasFormals) {
420420
for (auto & i : v.lambda().fun->getFormals()) {
421421
if (state->symbols[i.name] == "inNixShell") {
422422
add = true;

0 commit comments

Comments
 (0)