this finally gives us a witness type we can use to prove that a certain call graph subtree can't be used in kj promises using only a single new assumption: if EvalState& is never held as a reference member of a type and instead only ever passes as an argument or held on the stack we can be certain that anything that has access to en EvalState ref must never be run inside a promise and, crucially, that anything that doesn't have access to an EvalState& *can* be run inside a promise without problems. Change-Id: I6c15ada479175ad7e6cd3e4a729a5586b3ba30d6
89 lines
2.5 KiB
C++
89 lines
2.5 KiB
C++
#pragma once
|
|
///@file
|
|
|
|
#include "lix/libcmd/installable-value.hh"
|
|
#include "lix/libexpr/eval.hh"
|
|
|
|
namespace nix {
|
|
|
|
/**
|
|
* Extra info about a \ref DerivedPath "derived path" that ultimately
|
|
* come from a Flake.
|
|
*
|
|
* Invariant: every ExtraPathInfo gotten from an InstallableFlake should
|
|
* be possible to downcast to an ExtraPathInfoFlake.
|
|
*/
|
|
struct ExtraPathInfoFlake : ExtraPathInfoValue
|
|
{
|
|
/**
|
|
* Extra struct to get around C++ designated initializer limitations
|
|
*/
|
|
struct Flake {
|
|
FlakeRef originalRef;
|
|
FlakeRef lockedRef;
|
|
};
|
|
|
|
Flake flake;
|
|
|
|
ExtraPathInfoFlake(Value && v, Flake && f)
|
|
: ExtraPathInfoValue(std::move(v)), flake(f)
|
|
{ }
|
|
};
|
|
|
|
struct InstallableFlake : InstallableValue
|
|
{
|
|
FlakeRef flakeRef;
|
|
Strings attrPaths;
|
|
Strings prefixes;
|
|
ExtendedOutputsSpec extendedOutputsSpec;
|
|
const flake::LockFlags & lockFlags;
|
|
mutable std::shared_ptr<flake::LockedFlake> _lockedFlake;
|
|
|
|
InstallableFlake(
|
|
SourceExprCommand * cmd,
|
|
ref<eval_cache::CachingEvaluator> state,
|
|
FlakeRef && flakeRef,
|
|
std::string_view fragment,
|
|
ExtendedOutputsSpec extendedOutputsSpec,
|
|
Strings attrPaths,
|
|
Strings prefixes,
|
|
const flake::LockFlags & lockFlags);
|
|
|
|
std::string what() const override { return flakeRef.to_string() + "#" + *attrPaths.begin(); }
|
|
|
|
std::vector<std::string> getActualAttrPaths();
|
|
|
|
DerivedPathsWithInfo toDerivedPaths(EvalState & state) override;
|
|
|
|
std::pair<Value *, PosIdx> toValue(EvalState & state) override;
|
|
|
|
/**
|
|
* Get a cursor to every attrpath in getActualAttrPaths() that
|
|
* exists. However if none exists, throw an exception.
|
|
*/
|
|
std::vector<ref<eval_cache::AttrCursor>> getCursors(EvalState & state) override;
|
|
|
|
std::shared_ptr<flake::LockedFlake> getLockedFlake(EvalState & state) const;
|
|
|
|
FlakeRef nixpkgsFlakeRef(EvalState & state) const;
|
|
};
|
|
|
|
/**
|
|
* Default flake ref for referring to Nixpkgs. For flakes that don't
|
|
* have their own Nixpkgs input, or other installables.
|
|
*
|
|
* It is a layer violation for Nix to know about Nixpkgs; currently just
|
|
* `nix develop` does. Be wary of using this /
|
|
* `InstallableFlake::nixpkgsFlakeRef` more places.
|
|
*/
|
|
static inline FlakeRef defaultNixpkgsFlakeRef()
|
|
{
|
|
return FlakeRef::fromAttrs({{"type","indirect"}, {"id", "nixpkgs"}});
|
|
}
|
|
|
|
ref<eval_cache::EvalCache> openEvalCache(
|
|
eval_cache::CachingEvaluator & state,
|
|
std::shared_ptr<flake::LockedFlake> lockedFlake);
|
|
|
|
}
|