mirror of
https://github.com/privatevoid-net/nix-super.git
synced 2024-11-22 05:56:15 +02:00
C API: Require non-thunk value from primop definition
This commit is contained in:
parent
8884227045
commit
8ef6efc184
2 changed files with 50 additions and 0 deletions
|
@ -100,6 +100,15 @@ static void nix_c_primop_wrapper(
|
|||
.debugThrow();
|
||||
}
|
||||
|
||||
if (vTmp.type() == nix::nThunk) {
|
||||
// We might allow this in the future if it makes sense for the evaluator
|
||||
// e.g. implementing tail recursion by returning a thunk to the next
|
||||
// "iteration". Until then, this is most likely a mistake or misunderstanding.
|
||||
state.error<nix::EvalError>("Implementation error in custom function: return value must not be a thunk")
|
||||
.atPos(pos)
|
||||
.debugThrow();
|
||||
}
|
||||
|
||||
v = vTmp;
|
||||
}
|
||||
|
||||
|
|
|
@ -257,4 +257,45 @@ TEST_F(nix_api_expr_test, nix_expr_primop_bad_no_return)
|
|||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badNoReturn")));
|
||||
}
|
||||
|
||||
static void
|
||||
primop_bad_return_thunk(void * user_data, nix_c_context * context, EvalState * state, Value ** args, Value * ret)
|
||||
{
|
||||
nix_init_apply(context, ret, args[0], args[1]);
|
||||
}
|
||||
TEST_F(nix_api_expr_test, nix_expr_primop_bad_return_thunk)
|
||||
{
|
||||
PrimOp * primop =
|
||||
nix_alloc_primop(ctx, primop_bad_return_thunk, 2, "badReturnThunk", nullptr, "a broken primop", nullptr);
|
||||
assert_ctx_ok();
|
||||
Value * primopValue = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_primop(ctx, primopValue, primop);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * toString = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_expr_eval_from_string(ctx, state, "builtins.toString", ".", toString);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * four = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_init_int(ctx, four, 4);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * partial = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, primopValue, toString, partial);
|
||||
assert_ctx_ok();
|
||||
|
||||
Value * result = nix_alloc_value(ctx, state);
|
||||
assert_ctx_ok();
|
||||
nix_value_call(ctx, state, partial, four, result);
|
||||
|
||||
ASSERT_EQ(ctx->last_err_code, NIX_ERR_NIX_ERROR);
|
||||
ASSERT_THAT(
|
||||
ctx->last_err,
|
||||
testing::Optional(
|
||||
testing::HasSubstr("Implementation error in custom function: return value must not be a thunk")));
|
||||
ASSERT_THAT(ctx->last_err, testing::Optional(testing::HasSubstr("badReturnThunk")));
|
||||
}
|
||||
} // namespace nixC
|
||||
|
|
Loading…
Reference in a new issue