Skip to content

Commit fb68699

Browse files
authored
Merge pull request #9370 from hercules-ci/add-value-types
refactor: Add `Value` types, use `std::span` for list iteration
2 parents 4292d99 + 121665f commit fb68699

File tree

2 files changed

+61
-74
lines changed

2 files changed

+61
-74
lines changed

src/libexpr/value.hh

Lines changed: 60 additions & 73 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33

44
#include <cassert>
55
#include <climits>
6+
#include <span>
67

78
#include "symbol-table.hh"
89
#include "value/context.hh"
@@ -158,64 +159,72 @@ public:
158159
inline bool isPrimOp() const { return internalType == tPrimOp; };
159160
inline bool isPrimOpApp() const { return internalType == tPrimOpApp; };
160161

161-
union
162-
{
163-
NixInt integer;
164-
bool boolean;
162+
/**
163+
* Strings in the evaluator carry a so-called `context` which
164+
* is a list of strings representing store paths. This is to
165+
* allow users to write things like
166+
*
167+
* "--with-freetype2-library=" + freetype + "/lib"
168+
*
169+
* where `freetype` is a derivation (or a source to be copied
170+
* to the store). If we just concatenated the strings without
171+
* keeping track of the referenced store paths, then if the
172+
* string is used as a derivation attribute, the derivation
173+
* will not have the correct dependencies in its inputDrvs and
174+
* inputSrcs.
175+
176+
* The semantics of the context is as follows: when a string
177+
* with context C is used as a derivation attribute, then the
178+
* derivations in C will be added to the inputDrvs of the
179+
* derivation, and the other store paths in C will be added to
180+
* the inputSrcs of the derivations.
181+
182+
* For canonicity, the store paths should be in sorted order.
183+
*/
184+
struct StringWithContext {
185+
const char * c_str;
186+
const char * * context; // must be in sorted order
187+
};
165188

166-
/**
167-
* Strings in the evaluator carry a so-called `context` which
168-
* is a list of strings representing store paths. This is to
169-
* allow users to write things like
189+
struct Path {
190+
InputAccessor * accessor;
191+
const char * path;
192+
};
170193

171-
* "--with-freetype2-library=" + freetype + "/lib"
194+
struct ClosureThunk {
195+
Env * env;
196+
Expr * expr;
197+
};
172198

173-
* where `freetype` is a derivation (or a source to be copied
174-
* to the store). If we just concatenated the strings without
175-
* keeping track of the referenced store paths, then if the
176-
* string is used as a derivation attribute, the derivation
177-
* will not have the correct dependencies in its inputDrvs and
178-
* inputSrcs.
199+
struct FunctionApplicationThunk {
200+
Value * left, * right;
201+
};
179202

180-
* The semantics of the context is as follows: when a string
181-
* with context C is used as a derivation attribute, then the
182-
* derivations in C will be added to the inputDrvs of the
183-
* derivation, and the other store paths in C will be added to
184-
* the inputSrcs of the derivations.
203+
struct Lambda {
204+
Env * env;
205+
ExprLambda * fun;
206+
};
185207

186-
* For canonicity, the store paths should be in sorted order.
187-
*/
188-
struct {
189-
const char * c_str;
190-
const char * * context; // must be in sorted order
191-
} string;
208+
union
209+
{
210+
NixInt integer;
211+
bool boolean;
192212

193-
struct {
194-
InputAccessor * accessor;
195-
const char * path;
196-
} _path;
213+
StringWithContext string;
214+
215+
Path _path;
197216

198217
Bindings * attrs;
199218
struct {
200219
size_t size;
201220
Value * * elems;
202221
} bigList;
203222
Value * smallList[2];
204-
struct {
205-
Env * env;
206-
Expr * expr;
207-
} thunk;
208-
struct {
209-
Value * left, * right;
210-
} app;
211-
struct {
212-
Env * env;
213-
ExprLambda * fun;
214-
} lambda;
223+
ClosureThunk thunk;
224+
FunctionApplicationThunk app;
225+
Lambda lambda;
215226
PrimOp * primOp;
216-
struct {
217-
Value * left, * right;
218-
} primOpApp;
227+
FunctionApplicationThunk primOpApp;
219228
ExternalValueBase * external;
220229
NixFloat fpoint;
221230
};
@@ -387,7 +396,13 @@ public:
387396
return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems;
388397
}
389398

390-
const Value * const * listElems() const
399+
std::span<Value * const> listItems() const
400+
{
401+
assert(isList());
402+
return std::span<Value * const>(listElems(), listSize());
403+
}
404+
405+
Value * const * listElems() const
391406
{
392407
return internalType == tList1 || internalType == tList2 ? smallList : bigList.elems;
393408
}
@@ -406,34 +421,6 @@ public:
406421
*/
407422
bool isTrivial() const;
408423

409-
auto listItems()
410-
{
411-
struct ListIterable
412-
{
413-
typedef Value * const * iterator;
414-
iterator _begin, _end;
415-
iterator begin() const { return _begin; }
416-
iterator end() const { return _end; }
417-
};
418-
assert(isList());
419-
auto begin = listElems();
420-
return ListIterable { begin, begin + listSize() };
421-
}
422-
423-
auto listItems() const
424-
{
425-
struct ConstListIterable
426-
{
427-
typedef const Value * const * iterator;
428-
iterator _begin, _end;
429-
iterator begin() const { return _begin; }
430-
iterator end() const { return _end; }
431-
};
432-
assert(isList());
433-
auto begin = listElems();
434-
return ConstListIterable { begin, begin + listSize() };
435-
}
436-
437424
SourcePath path() const
438425
{
439426
assert(internalType == tPath);

src/nix-env/nix-env.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -172,7 +172,7 @@ static void loadSourceExpr(EvalState & state, const SourcePath & path, Value & v
172172
directory). */
173173
else if (st.type == InputAccessor::tDirectory) {
174174
auto attrs = state.buildBindings(maxAttrs);
175-
attrs.alloc("_combineChannels").mkList(0);
175+
state.mkList(attrs.alloc("_combineChannels"), 0);
176176
StringSet seen;
177177
getAllExprs(state, path, seen, attrs);
178178
v.mkAttrs(attrs);

0 commit comments

Comments
 (0)