repl: --option pure-eval true actually enables pure eval mode

To quote Eelco in #5867:

> Unfortunately we can't do
>
>     evalSettings.pureEval.setDefault(false);
>
> because then we have to do the same in main.cc (where
> pureEval is set to true), and that would allow pure-eval
> to be disabled globally from nix.conf.

Instead, a command should specify that it should be impure by
default. Then, `evalSettings.pureEval` will be set to `false;` unless
it's overridden by e.g. a CLI flag.

In that case it's IMHO OK to be (theoretically) able to override
`pure-eval` via `nix.conf` because it doesn't have an effect on commands
where `forceImpureByDefault` returns `false` (i.e. everything where pure
eval actually matters).

Closes #5867
This commit is contained in:
Maximilian Bosch 2022-01-31 18:03:24 +01:00
parent 078c80f750
commit 159b5815b5
No known key found for this signature in database
GPG key ID: 091DBF4D1FC46B8E
4 changed files with 15 additions and 2 deletions

View file

@ -1039,6 +1039,11 @@ struct CmdRepl : StoreCommand, MixEvalArgs
}); });
} }
bool forceImpureByDefault() override
{
return true;
}
std::string description() override std::string description() override
{ {
return "start an interactive environment for evaluating Nix expressions"; return "start an interactive environment for evaluating Nix expressions";
@ -1053,8 +1058,6 @@ struct CmdRepl : StoreCommand, MixEvalArgs
void run(ref<Store> store) override void run(ref<Store> store) override
{ {
evalSettings.pureEval = false;
auto evalState = make_ref<EvalState>(searchPath, store); auto evalState = make_ref<EvalState>(searchPath, store);
auto repl = std::make_unique<NixRepl>(evalState); auto repl = std::make_unique<NixRepl>(evalState);

View file

@ -25,6 +25,8 @@ public:
/* Return a short one-line description of the command. */ /* Return a short one-line description of the command. */
virtual std::string description() { return ""; } virtual std::string description() { return ""; }
virtual bool forceImpureByDefault() { return false; }
/* Return documentation about this command, in Markdown format. */ /* Return documentation about this command, in Markdown format. */
virtual std::string doc() { return ""; } virtual std::string doc() { return ""; }

View file

@ -380,6 +380,9 @@ void mainWrapped(int argc, char * * argv)
settings.ttlPositiveNarInfoCache = 0; settings.ttlPositiveNarInfoCache = 0;
} }
if (args.command->second->forceImpureByDefault() && !evalSettings.pureEval.overridden) {
evalSettings.pureEval = false;
}
args.command->second->prepare(); args.command->second->prepare();
args.command->second->run(); args.command->second->run();
} }

View file

@ -42,6 +42,11 @@ testRepl () {
echo "$replOutput" echo "$replOutput"
echo "$replOutput" | grep -qs "while evaluating the file" \ echo "$replOutput" | grep -qs "while evaluating the file" \
|| fail "nix repl --show-trace doesn't show the trace" || fail "nix repl --show-trace doesn't show the trace"
nix repl "${nixArgs[@]}" --option pure-eval true 2>&1 <<< "builtins.currentSystem" \
| grep "attribute 'currentSystem' missing"
nix repl "${nixArgs[@]}" 2>&1 <<< "builtins.currentSystem" \
| grep "$(nix-instantiate --eval -E 'builtins.currentSystem')"
} }
# Simple test, try building a drv # Simple test, try building a drv