diff --git a/ci/gha/tests/default.nix b/ci/gha/tests/default.nix index c179174e6e2..4a30a96a475 100644 --- a/ci/gha/tests/default.nix +++ b/ci/gha/tests/default.nix @@ -82,6 +82,11 @@ rec { ''; repl-completion = pkgs.callPackage ../../../tests/repl-completion.nix { inherit (packages') nix; }; + lazyTrees = nixComponents.nix-functional-tests.override { + pname = "nix-lazy-trees-tests"; + lazyTrees = true; + }; + /** Checks for our packaging expressions. This shouldn't build anything significant; just check that things diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index e1df04f2624..1a4b01805ad 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -4729,8 +4729,9 @@ static void prim_hashString(EvalState & state, const PosIdx pos, Value ** args, state.error("unknown hash algorithm '%1%'", algo).atPos(pos).debugThrow(); NixStringContext context; // discarded - auto s = - state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.hashString"); + auto s = state.devirtualize( + state.forceString(*args[1], context, pos, "while evaluating the second argument passed to builtins.hashString"), + context); v.mkString(hashString(*ha, s).to_string(HashFormat::Base16, false), state.mem); } diff --git a/src/nix/app.cc b/src/nix/app.cc index 07c7c55cfdb..4a8ca815c0f 100644 --- a/src/nix/app.cc +++ b/src/nix/app.cc @@ -90,7 +90,7 @@ UnresolvedApp InstallableValue::toApp(EvalState & state) }, [&](const NixStringContextElem::Opaque & o) -> DerivedPath { return DerivedPath::Opaque{ - .path = o.path, + .path = state.devirtualize(o.path), }; }, [&](const NixStringContextElem::Path & p) -> DerivedPath { @@ -102,7 +102,7 @@ UnresolvedApp InstallableValue::toApp(EvalState & state) return UnresolvedApp{App{ .context = std::move(context2), - .program = program, + .program = state.devirtualize(program, context), }}; } diff --git a/tests/functional/fetchGit.sh b/tests/functional/fetchGit.sh index 1d8a8e75224..d43108e6d2a 100755 --- a/tests/functional/fetchGit.sh +++ b/tests/functional/fetchGit.sh @@ -363,3 +363,17 @@ rm "$TEST_ROOT"/flake/flake.lock nix eval "path:$TEST_ROOT/flake"#isModern nix eval --nix-219-compat "path:$TEST_ROOT/flake"#isModern [[ $(jq -r .nodes.eol.locked.narHash < "$TEST_ROOT"/flake/flake.lock) = "$newHash" ]] + + +# Test that builtins.hashString devirtualizes lazy paths (https://github.com/DeterminateSystems/determinate/issues/160). +hashStringRepo="$TEST_ROOT/hashString" +createGitRepo "$hashStringRepo" +echo hello > "$hashStringRepo"/hello +git -C "$hashStringRepo" add hello +git -C "$hashStringRepo" commit -m 'Initial' +hashStringRev=$(git -C "$hashStringRepo" rev-parse HEAD) + +hash1=$(nix eval --lazy-trees --raw --expr "builtins.hashString \"sha256\" (toString ((builtins.fetchGit { url = file://$hashStringRepo; rev = \"$hashStringRev\"; })))") +hash2=$(nix eval --lazy-trees --raw --expr "builtins.hashString \"sha256\" (toString ((builtins.fetchGit { url = file://$hashStringRepo; rev = \"$hashStringRev\"; })))") + +[[ "$hash1" = "$hash2" ]]