1
0
Fork 0
mirror of https://github.com/NixOS/nix synced 2025-06-27 12:41:15 +02:00

Merge remote-tracking branch 'origin/master' into coerce-string

This commit is contained in:
Guillaume Maudoux 2022-04-29 00:12:25 +02:00
commit e93b59fbc5
170 changed files with 4010 additions and 2203 deletions

View file

@ -23,14 +23,14 @@ class StorePath;
enum RepairFlag : bool;
typedef void (* PrimOpFun) (EvalState & state, const Pos & pos, Value * * args, Value & v);
typedef void (* PrimOpFun) (EvalState & state, const PosIdx pos, Value * * args, Value & v);
struct PrimOp
{
PrimOpFun fun;
size_t arity;
Symbol name;
std::string name;
std::vector<std::string> args;
const char * doc = nullptr;
};
@ -53,7 +53,8 @@ void copyContext(const Value & v, PathSet & context);
typedef std::map<Path, StorePath> SrcToStore;
std::ostream & operator << (std::ostream & str, const Value & v);
std::ostream & printValue(const EvalState & state, std::ostream & str, const Value & v);
std::string printValue(const EvalState & state, const Value & v);
typedef std::pair<std::string, std::string> SearchPathElem;
@ -73,12 +74,15 @@ class EvalState
{
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,
sRight, sWrong, sStructuredAttrs, sBuilder, sArgs,
sContentAddressed,
sContentAddressed, sImpure,
sOutputHash, sOutputHashAlgo, sOutputHashMode,
sRecurseForDerivations,
sDescription, sSelf, sEpsilon, sStartSet, sOperator, sKey, sPath,
@ -149,12 +153,6 @@ public:
std::shared_ptr<Store> buildStore = nullptr);
~EvalState();
void requireExperimentalFeatureOnEvaluation(
const ExperimentalFeature &,
const std::string_view fName,
const Pos & pos
);
void addToSearchPath(const std::string & s);
SearchPath getSearchPath() { return searchPath; }
@ -211,7 +209,7 @@ public:
/* Look up a file in the search path. */
Path findFile(const std::string_view path);
Path findFile(SearchPath & searchPath, const std::string_view path, const Pos & pos = noPos);
Path findFile(SearchPath & searchPath, const std::string_view path, const PosIdx pos = noPos);
/* If the specified search path element is a URI, download it. */
std::pair<bool, std::string> resolveSearchPathElem(const SearchPathElem & elem);
@ -222,14 +220,15 @@ public:
/* Evaluation the expression, then verify that it has the expected
type. */
inline bool evalBool(Env & env, Expr * e, const Pos & pos, std::string_view errorCtx);
inline void evalAttrs(Env & env, Expr * e, Value & v, const Pos & pos, std::string_view errorCtx);
inline bool evalBool(Env & env, Expr * e);
inline bool evalBool(Env & env, Expr * e, const PosIdx pos, std::string_view errorCtx);
inline void evalAttrs(Env & env, Expr * e, Value & v, const PosIdx pos, std::string_view errorCtx);
/* If `v' is a thunk, enter it and overwrite `v' with the result
of the evaluation of the thunk. If `v' is a delayed function
application, call the function and overwrite `v' with the
result. Otherwise, this is a no-op. */
inline void forceValue(Value & v, const Pos & pos);
inline void forceValue(Value & v, const PosIdx pos);
template <typename Callable>
inline void forceValue(Value & v, Callable getPos);
@ -239,33 +238,61 @@ public:
void forceValueDeep(Value & v);
/* Force `v', and then verify that it has the expected type. */
NixInt forceInt(Value & v, const Pos & pos, std::string_view errorCtx);
NixFloat forceFloat(Value & v, const Pos & pos, std::string_view errorCtx);
bool forceBool(Value & v, const Pos & pos, std::string_view errorCtx);
NixInt forceInt(Value & v, const PosIdx pos, std::string_view errorCtx);
NixFloat forceFloat(Value & v, const PosIdx pos, std::string_view errorCtx);
bool forceBool(Value & v, const PosIdx pos, std::string_view errorCtx);
void forceAttrs(Value & v, const Pos & pos, std::string_view errorCtx);
void forceAttrs(Value & v, const PosIdx pos, std::string_view errorCtx);
template <typename Callable>
inline void forceAttrs(Value & v, Callable getPos, std::string_view errorCtx);
inline void forceList(Value & v, const Pos & pos, std::string_view errorCtx);
void forceFunction(Value & v, const Pos & pos, std::string_view errorCtx); // either lambda or primop
std::string_view forceString(Value & v, const Pos & pos, std::string_view errorCtx);
std::string_view forceString(Value & v, PathSet & context, const Pos & pos, std::string_view errorCtx);
std::string_view forceStringNoCtx(Value & v, const Pos & pos, std::string_view errorCtx);
inline void forceList(Value & v, const PosIdx pos, std::string_view errorCtx);
void forceFunction(Value & v, const PosIdx pos, std::string_view errorCtx); // either lambda or primop
std::string_view forceString(Value & v, const PosIdx pos, std::string_view errorCtx);
std::string_view forceString(Value & v, PathSet & context, const PosIdx pos, std::string_view errorCtx);
std::string_view forceStringNoCtx(Value & v, const PosIdx pos, std::string_view errorCtx);
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const Value & v) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const Suggestions & suggestions, const char * s, const std::string_view s2) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string_view s2) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const std::string_view s2, const std::string_view s3) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx pos, const char * s, const std::string & s2, const std::string & s3) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const PosIdx p1, const char * s, const Symbol sym, const PosIdx p2) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalError(const char * s, const Value & v) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const Value & v) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const char * s, const ExprLambda & fun, const Symbol s2) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const PosIdx pos, const Suggestions & suggestions, const char * s, const ExprLambda & fun, const Symbol s2) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeError(const char * s, const Value & v) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const PosIdx, const nix::Suggestions&, const char*, std::string_view, const nix::Symbol&, const PosIdx, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const Pos &, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwTypeErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, const PosIdx, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwEvalErrorWithTrace(const char*, std::string_view, std::string_view, nix::PosIdx, std::string_view) const;
[[gnu::noinline, gnu::noreturn]] void throwAssertionError(const PosIdx pos, const char * s, const std::string & s1) const;
[[gnu::noinline, gnu::noreturn]] void throwUndefinedVarError(const PosIdx pos, const char * s, const std::string & s1) const;
[[gnu::noinline, gnu::noreturn]] void throwMissingArgumentError(const PosIdx pos, const char * s, const std::string & s1) const;
[[gnu::noinline]] void addErrorTrace(Error & e, const char * s, const std::string & s2) const;
[[gnu::noinline]] void addErrorTrace(Error & e, const PosIdx pos, const char * s, const std::string & s2) const;
public:
/* Return true iff the value `v' denotes a derivation (i.e. a
set with attribute `type = "derivation"'). */
bool isDerivation(Value & v);
std::optional<std::string> tryAttrsToString(const Pos & pos, Value & v,
std::optional<std::string> tryAttrsToString(const PosIdx pos, Value & v,
PathSet & context, bool coerceMore = false, bool copyToStore = true);
/* String coercion. Converts strings, paths and derivations to a
string. If `coerceMore' is set, also converts nulls, integers,
booleans and lists to a string. If `copyToStore' is set,
referenced paths are copied to the Nix store as a side effect. */
BackedStringView coerceToString(const Pos & pos, Value & v, PathSet & context,
BackedStringView coerceToString(const PosIdx pos, Value & v, PathSet & context,
bool coerceMore = false, bool copyToStore = true,
bool canonicalizePath = true,
std::string_view errorCtx = "");
@ -275,10 +302,10 @@ public:
/* Path coercion. Converts strings, paths and derivations to a
path. The result is guaranteed to be a canonicalised, absolute
path. Nothing is copied to the store. */
Path coerceToPath(const Pos & pos, Value & v, PathSet & context, std::string_view errorCtx);
Path coerceToPath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx);
/* Like coerceToPath, but the result must be a store path. */
StorePath coerceToStorePath(const Pos & pos, Value & v, PathSet & context, std::string_view errorCtx);
StorePath coerceToStorePath(const PosIdx pos, Value & v, PathSet & context, std::string_view errorCtx);
public:
@ -311,7 +338,7 @@ public:
struct Doc
{
Pos pos;
std::optional<Symbol> name;
std::optional<std::string> name;
size_t arity;
std::vector<std::string> args;
const char * doc;
@ -334,14 +361,14 @@ public:
/* Do a deep equality test between two values. That is, list
elements and attributes are compared recursively. */
bool eqValues(Value & v1, Value & v2, const Pos & pos, std::string_view errorCtx);
bool eqValues(Value & v1, Value & v2, const PosIdx pos, std::string_view errorCtx);
bool isFunctor(Value & fun);
// FIXME: use std::span
void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const Pos & pos);
void callFunction(Value & fun, size_t nrArgs, Value * * args, Value & vRes, const PosIdx pos);
void callFunction(Value & fun, Value & arg, Value & vRes, const Pos & pos)
void callFunction(Value & fun, Value & arg, Value & vRes, const PosIdx pos)
{
Value * args[] = {&arg};
callFunction(fun, 1, args, vRes, pos);
@ -355,7 +382,7 @@ public:
inline Value * allocValue();
inline Env & allocEnv(size_t size);
Value * allocAttr(Value & vAttrs, const Symbol & name);
Value * allocAttr(Value & vAttrs, Symbol name);
Value * allocAttr(Value & vAttrs, std::string_view name);
Bindings * allocBindings(size_t capacity);
@ -367,9 +394,9 @@ public:
void mkList(Value & v, size_t length);
void mkThunk_(Value & v, Expr * expr);
void mkPos(Value & v, ptr<Pos> pos);
void mkPos(Value & v, PosIdx pos);
void concatLists(Value & v, size_t nrLists, Value * * lists, const Pos & pos, std::string_view errorCtx);
void concatLists(Value & v, size_t nrLists, Value * * lists, const PosIdx pos, std::string_view errorCtx);
/* Print statistics. */
void printStats();
@ -397,7 +424,7 @@ private:
bool countCalls;
typedef std::map<Symbol, size_t> PrimOpCalls;
typedef std::map<std::string, size_t> PrimOpCalls;
PrimOpCalls primOpCalls;
typedef std::map<ExprLambda *, size_t> FunctionCalls;
@ -405,7 +432,7 @@ private:
void incrFunctionCall(ExprLambda * fun);
typedef std::map<Pos, size_t> AttrSelects;
typedef std::map<PosIdx, size_t> AttrSelects;
AttrSelects attrSelects;
friend struct ExprOpUpdate;
@ -416,9 +443,9 @@ private:
friend struct ExprFloat;
friend struct ExprPath;
friend struct ExprSelect;
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v);
friend void prim_match(EvalState & state, const Pos & pos, Value * * args, Value & v);
friend void prim_split(EvalState & state, const Pos & pos, Value * * args, Value & v);
friend void prim_getAttr(EvalState & state, const PosIdx pos, Value * * args, Value & v);
friend void prim_match(EvalState & state, const PosIdx pos, Value * * args, Value & v);
friend void prim_split(EvalState & state, const PosIdx pos, Value * * args, Value & v);
friend struct Value;
};
@ -430,7 +457,7 @@ std::string showType(const Value & v);
/* Decode a context string !<name>!<path> into a pair <path,
name>. */
std::pair<std::string, std::string> decodeContext(std::string_view s);
NixStringContextElem decodeContext(const Store & store, std::string_view s);
/* If `path' refers to a directory, then append "/default.nix". */
Path resolveExprPath(Path path);