diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 497a1e8f5..cf90d1da6 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -475,6 +475,10 @@ EvalState::EvalState( throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation); })) , corepkgsFS(makeMemoryInputAccessor()) + , derivationInternal{corepkgsFS->addFile( + CanonPath("derivation-internal.nix"), + #include "primops/derivation.nix.gen.hh" + )} , store(store) , buildStore(buildStore ? buildStore : store) , debugRepl(0) @@ -508,12 +512,12 @@ EvalState::EvalState( for (auto & i : searchPath) resolveSearchPathElem(i, true); - createBaseEnv(); - corepkgsFS->addFile( CanonPath("fetchurl.nix"), #include "fetchurl.nix.gen.hh" ); + + createBaseEnv(); } @@ -1449,11 +1453,13 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v) state.forceValue(*vAttrs, (pos2 ? pos2 : this->pos ) ); } catch (Error & e) { - auto pos2r = state.positions[pos2]; - // FIXME: use MemoryAccessor - if (pos2 /* && pos2r.origin != Pos(state.derivationNixPath) */) - state.addErrorTrace(e, pos2, "while evaluating the attribute '%1%'", - showAttrPath(state, env, attrPath)); + if (pos2) { + auto pos2r = state.positions[pos2]; + auto origin = std::get_if(&pos2r.origin); + if (!origin || *origin != state.derivationInternal) + state.addErrorTrace(e, pos2, "while evaluating the attribute '%1%'", + showAttrPath(state, env, attrPath)); + } throw; } diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index f9814b501..de8fb4e8b 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -91,8 +91,6 @@ public: SymbolTable symbols; PosTable positions; - static inline std::string derivationNixPath = "//builtin/derivation.nix"; - const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue, sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls, sFile, sLine, sColumn, sFunctor, sToString, @@ -103,7 +101,6 @@ public: sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath, sPrefix, sOutputSpecified; - Symbol sDerivationNix; /* If set, force copying files to the Nix store even if they already exist there. */ @@ -111,8 +108,10 @@ public: Bindings emptyBindings; - ref rootFS; - ref corepkgsFS; + const ref rootFS; + const ref corepkgsFS; + + const SourcePath derivationInternal; std::unordered_map> inputAccessors; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index 8f8711e8c..5d63c1776 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -3979,8 +3979,6 @@ void EvalState::createBaseEnv() /* Add a wrapper around the derivation primop that computes the `drvPath' and `outPath' attributes lazily. */ - // FIXME: use corepkgsFS. - sDerivationNix = symbols.create(derivationNixPath); auto vDerivation = allocValue(); addConstant("derivation", vDerivation); @@ -3992,12 +3990,7 @@ void EvalState::createBaseEnv() /* Note: we have to initialize the 'derivation' constant *after* building baseEnv/staticBaseEnv because it uses 'builtins'. */ - char code[] = - #include "primops/derivation.nix.gen.hh" - // the parser needs two NUL bytes as terminators; one of them - // is implied by being a C string. - "\0"; - eval(parse(code, sizeof(code), Pos::string_tag(), rootPath("/"), staticBaseEnv), *vDerivation); + evalFile(derivationInternal, *vDerivation); } diff --git a/src/libfetchers/input-accessor.cc b/src/libfetchers/input-accessor.cc index a335f1e10..ce1327fda 100644 --- a/src/libfetchers/input-accessor.cc +++ b/src/libfetchers/input-accessor.cc @@ -258,9 +258,11 @@ struct MemoryInputAccessorImpl : MemoryInputAccessor throw UnimplementedError("MemoryInputAccessor::readLink"); } - void addFile(CanonPath path, std::string && contents) override + SourcePath addFile(CanonPath path, std::string && contents) override { - files.emplace(std::move(path), std::move(contents)); + files.emplace(path, std::move(contents)); + + return {ref(shared_from_this()), std::move(path)}; } }; diff --git a/src/libfetchers/input-accessor.hh b/src/libfetchers/input-accessor.hh index 46ae48b2a..3160eaf28 100644 --- a/src/libfetchers/input-accessor.hh +++ b/src/libfetchers/input-accessor.hh @@ -77,9 +77,11 @@ ref makeFSInputAccessor( std::optional> && allowedPaths = {}, MakeNotAllowedError && makeNotAllowedError = {}); +struct SourcePath; + struct MemoryInputAccessor : InputAccessor { - virtual void addFile(CanonPath path, std::string && contents) = 0; + virtual SourcePath addFile(CanonPath path, std::string && contents) = 0; }; ref makeMemoryInputAccessor();