diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 84f14198f82..b160fde0179 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -1075,11 +1075,9 @@ struct ExprParseFile : Expr, gc { // FIXME: make this a reference (see below). SourcePath path; - bool mustBeTrivial; - ExprParseFile(SourcePath & path, bool mustBeTrivial) + ExprParseFile(SourcePath & path) : path(path) - , mustBeTrivial(mustBeTrivial) { } @@ -1096,11 +1094,6 @@ struct ExprParseFile : Expr, gc state, *e, state.baseEnv, e->getPos(), "while evaluating the file '%s':", path.to_string()) : nullptr; - // Enforce that 'flake.nix' is a direct attrset, not a - // computation. - if (mustBeTrivial && !(dynamic_cast(e))) - state.error("file '%s' must be an attribute set", path).debugThrow(); - state.eval(e, v); } catch (Error & e) { state.addErrorTrace(e, "while evaluating the file '%s':", path.to_string()); @@ -1109,7 +1102,7 @@ struct ExprParseFile : Expr, gc } }; -void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial) +void EvalState::evalFile(const SourcePath & path, Value & v) { auto resolvedPath = getConcurrent(*importResolutionCache, path); @@ -1129,7 +1122,7 @@ void EvalState::evalFile(const SourcePath & path, Value & v, bool mustBeTrivial) // https://github.com/NixOS/nix/pull/13930 is merged. That will ensure // the post-condition that `expr` is unreachable after // `forceValue()` returns. - auto expr = new ExprParseFile{*resolvedPath, mustBeTrivial}; + auto expr = new ExprParseFile{*resolvedPath}; fileEvalCache->try_emplace_and_cvisit( *resolvedPath, diff --git a/src/libexpr/include/nix/expr/eval.hh b/src/libexpr/include/nix/expr/eval.hh index 29acb4547aa..58458dc9755 100644 --- a/src/libexpr/include/nix/expr/eval.hh +++ b/src/libexpr/include/nix/expr/eval.hh @@ -610,7 +610,7 @@ public: * form. Optionally enforce that the top-level expression is * trivial (i.e. doesn't require arbitrary computation). */ - void evalFile(const SourcePath & path, Value & v, bool mustBeTrivial = false); + void evalFile(const SourcePath & path, Value & v); void resetFileCache(); diff --git a/src/libflake/flake.cc b/src/libflake/flake.cc index be3b667d2da..4cd39c0f625 100644 --- a/src/libflake/flake.cc +++ b/src/libflake/flake.cc @@ -69,15 +69,9 @@ using namespace flake; namespace flake { -static void forceTrivialValue(EvalState & state, Value & value, const PosIdx pos) -{ - if (value.isThunk() && value.isTrivial()) - state.forceValue(value, pos); -} - static void expectType(EvalState & state, ValueType type, Value & value, const PosIdx pos) { - forceTrivialValue(state, value, pos); + state.forceValue(value, pos); if (value.type() != type) throw Error("expected %s but got %s at %s", showType(type), showType(value.type()), state.positions[pos]); } @@ -151,7 +145,7 @@ static FlakeInput parseFlakeInput( for (auto & attr : *value->attrs()) { try { if (attr.name == sUrl) { - forceTrivialValue(state, *attr.value, pos); + state.forceValue(*attr.value, pos); if (attr.value->type() == nString) url = attr.value->string_view(); else if (attr.value->type() == nPath) { @@ -224,6 +218,7 @@ static std::pair, fetchers::Attrs> parseFlakeInput expectType(state, nAttrs, *value, pos); for (auto & inputAttr : *value->attrs()) { + state.forceValue(*inputAttr.value, pos); auto inputName = state.symbols[inputAttr.name]; if (inputName == "self") { if (!allowSelf) @@ -251,9 +246,8 @@ static Flake readFlake( auto flakeDir = rootDir / CanonPath(resolvedRef.subdir); auto flakePath = flakeDir / "flake.nix"; - // NOTE evalFile forces vInfo to be an attrset because mustBeTrivial is true. Value vInfo; - state.evalFile(flakePath, vInfo, true); + state.evalFile(flakePath, vInfo); Flake flake{ .originalRef = originalRef, @@ -302,7 +296,7 @@ static Flake readFlake( expectType(state, nAttrs, *nixConfig->value, nixConfig->pos); for (auto & setting : *nixConfig->value->attrs()) { - forceTrivialValue(state, *setting.value, setting.pos); + state.forceValue(*setting.value, setting.pos); if (setting.value->type() == nString) flake.config.settings.emplace( state.symbols[setting.name], std::string(state.forceStringNoCtx(*setting.value, setting.pos, "")));