fix: use forceBool in codegen

This commit is contained in:
2026-01-22 16:46:11 +08:00
parent 041d7b7dd2
commit 43b8959842
2 changed files with 7 additions and 5 deletions

View File

@@ -24,6 +24,7 @@ import { builtins, PRIMOP_METADATA } from "./builtins";
import { coerceToString, StringCoercionMode } from "./builtins/conversion"; import { coerceToString, StringCoercionMode } from "./builtins/conversion";
import { HAS_CONTEXT } from "./string-context"; import { HAS_CONTEXT } from "./string-context";
import { IS_PATH } from "./types"; import { IS_PATH } from "./types";
import { forceBool } from "./type-assert";
export type NixRuntime = typeof Nix; export type NixRuntime = typeof Nix;
@@ -33,6 +34,7 @@ export type NixRuntime = typeof Nix;
export const Nix = { export const Nix = {
createThunk, createThunk,
force, force,
forceBool,
isThunk, isThunk,
IS_THUNK, IS_THUNK,
HAS_CONTEXT, HAS_CONTEXT,

View File

@@ -98,11 +98,11 @@ impl<Ctx: CodegenContext> Compile<Ctx> for Ir {
if std::env::var("NIX_JS_STACK_TRACE").is_ok() { if std::env::var("NIX_JS_STACK_TRACE").is_ok() {
let cond_span = encode_span(ctx.get_ir(cond).span(), ctx); let cond_span = encode_span(ctx.get_ir(cond).span(), ctx);
format!( format!(
"(Nix.withContext(\"while evaluating a branch condition\",{},()=>({})))?({}):({})", "(Nix.withContext(\"while evaluating a branch condition\",{},()=>Nix.forceBool({})))?({}):({})",
cond_span, cond_code, consq, alter cond_span, cond_code, consq, alter
) )
} else { } else {
format!("({cond_code})?({consq}):({alter})") format!("Nix.forceBool({cond_code})?({consq}):({alter})")
} }
} }
Ir::BinOp(x) => x.compile(ctx), Ir::BinOp(x) => x.compile(ctx),
@@ -196,9 +196,9 @@ impl<Ctx: CodegenContext> Compile<Ctx> for BinOp {
Leq => with_ctx("<=", format!("Nix.op.lte({},{})", lhs, rhs)), Leq => with_ctx("<=", format!("Nix.op.lte({},{})", lhs, rhs)),
Geq => with_ctx(">=", format!("Nix.op.gte({},{})", lhs, rhs)), Geq => with_ctx(">=", format!("Nix.op.gte({},{})", lhs, rhs)),
// Short-circuit operators: use JavaScript native && and || // Short-circuit operators: use JavaScript native && and ||
And => with_ctx("&&", format!("Nix.force({})&&Nix.force({})", lhs, rhs)), And => with_ctx("&&", format!("Nix.forceBool({})&&Nix.forceBool({})", lhs, rhs)),
Or => with_ctx("||", format!("Nix.force({})||Nix.force({})", lhs, rhs)), Or => with_ctx("||", format!("Nix.forceBool({})||Nix.forceBool({})", lhs, rhs)),
Impl => with_ctx("->", format!("(!Nix.force({})||Nix.force({}))", lhs, rhs)), Impl => with_ctx("->", format!("(!Nix.forceBool({})||Nix.forceBool({}))", lhs, rhs)),
Con => with_ctx("++", format!("Nix.op.concat({},{})", lhs, rhs)), Con => with_ctx("++", format!("Nix.op.concat({},{})", lhs, rhs)),
Upd => with_ctx("//", format!("Nix.op.update({},{})", lhs, rhs)), Upd => with_ctx("//", format!("Nix.op.update({},{})", lhs, rhs)),
PipeL => format!("Nix.call({},{})", rhs, lhs), PipeL => format!("Nix.call({},{})", rhs, lhs),