1
1
Fork 0
mirror of https://github.com/NixOS/nix.git synced 2025-11-20 01:09:37 +01:00

Re-split the function, but without the exception

This commit is contained in:
regnat 2021-06-02 17:08:56 +02:00
parent 4ca1a0b864
commit 44f390ed48
2 changed files with 11 additions and 35 deletions

View file

@ -1109,9 +1109,7 @@ void ExprVar::eval(EvalState & state, Env & env, Value & v)
unsigned long nrLookups = 0; unsigned long nrLookups = 0;
MakeError(MissingField, Error); bool EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
void EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest)
{ {
Pos * pos2 = 0; Pos * pos2 = 0;
@ -1123,7 +1121,7 @@ void EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
forceValue(*vAttrs, pos); forceValue(*vAttrs, pos);
if (vAttrs->type() != nAttrs || if (vAttrs->type() != nAttrs ||
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) { (j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) {
throw MissingField("attribute '%s' missing", name); return false;
} }
vAttrs = j->value; vAttrs = j->value;
pos2 = j->pos; pos2 = j->pos;
@ -1141,6 +1139,7 @@ void EvalState::getAttrField(Value & attrs, const std::vector<Symbol> & selector
} }
dest = *vAttrs; dest = *vAttrs;
return true;
} }
void ExprSelect::eval(EvalState & state, Env & env, Value & v) void ExprSelect::eval(EvalState & state, Env & env, Value & v)
@ -1153,38 +1152,15 @@ void ExprSelect::eval(EvalState & state, Env & env, Value & v)
for (auto & i : attrPath) for (auto & i : attrPath)
selector.push_back(getName(i, state, env)); selector.push_back(getName(i, state, env));
Pos * pos2 = 0; bool gotField = state.getAttrField(vTmp, selector, pos, v);
if (!gotField) {
Value * vAttrs = &vTmp;
try {
for (auto & name : selector) {
nrLookups++;
Bindings::iterator j;
state.forceValue(*vAttrs, pos);
if (vAttrs->type() != nAttrs ||
(j = vAttrs->attrs->find(name)) == vAttrs->attrs->end()) {
if (def) { if (def) {
def->eval(state, env, v); def->eval(state, env, v);
return; return;
} else {
throwEvalError(pos, "Missing field");
} }
throwEvalError(pos, "attribute '%s' missing", name);
} }
vAttrs = j->value;
pos2 = j->pos;
if (state.countCalls && pos2) state.attrSelects[*pos2]++;
}
state.forceValue(*vAttrs, ( pos2 != NULL ? *pos2 : pos ) );
} catch (Error & e) {
if (pos2 && pos2->file != state.sDerivationNix) {
vector<string> strSelector;
addErrorTrace(e, *pos2, "while evaluating the attribute '%1%'", concatStringsSep(".", selector));
}
throw;
}
v = *vAttrs;
} }

View file

@ -344,7 +344,7 @@ private:
friend void prim_getAttr(EvalState & state, const Pos & pos, Value * * args, Value & v); 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_match(EvalState & state, const Pos & pos, Value * * args, Value & v);
void getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest); bool getAttrField(Value & attrs, const std::vector<Symbol> & selector, const Pos & pos, Value & dest);
}; };