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)
{ {
forceValue(v); std::set<const Value *> seen;
if (v.type == tAttrs) { std::function<void(Value & v)> recurse;
foreach (Bindings::iterator, i, *v.attrs)
forceValueDeep(*i->value);
}
else if (v.type == tList) { recurse = [&](Value & v) {
for (unsigned int n = 0; n < v.list.length; ++n) if (seen.find(&v) != seen.end()) return;
forceValueDeep(*v.list.elems[n]); seen.insert(&v);
}
forceValue(v);
if (v.type == tAttrs) {
foreach (Bindings::iterator, i, *v.attrs)
recurse(*i->value);
}
else if (v.type == tList) {
for (unsigned int n = 0; n < v.list.length; ++n)
recurse(*v.list.elems[n]);
}
};
recurse(v);
} }