Make forceValueDeep work on values with cycles

This commit is contained in:
Eelco Dolstra 2014-09-22 15:16:09 +02:00
parent 1e0a799bef
commit 831fc8ea21

View file

@ -1183,17 +1183,28 @@ void ExprPos::eval(EvalState & state, Env & env, Value & v)
void EvalState::forceValueDeep(Value & v) void EvalState::forceValueDeep(Value & v)
{ {
std::set<const Value *> seen;
std::function<void(Value & v)> recurse;
recurse = [&](Value & v) {
if (seen.find(&v) != seen.end()) return;
seen.insert(&v);
forceValue(v); forceValue(v);
if (v.type == tAttrs) { if (v.type == tAttrs) {
foreach (Bindings::iterator, i, *v.attrs) foreach (Bindings::iterator, i, *v.attrs)
forceValueDeep(*i->value); recurse(*i->value);
} }
else if (v.type == tList) { else if (v.type == tList) {
for (unsigned int n = 0; n < v.list.length; ++n) for (unsigned int n = 0; n < v.list.length; ++n)
forceValueDeep(*v.list.elems[n]); recurse(*v.list.elems[n]);
} }
};
recurse(v);
} }