diff --git a/src/libexpr/eval.cc b/src/libexpr/eval.cc index 814c19efcc..4c448ff51a 100644 --- a/src/libexpr/eval.cc +++ b/src/libexpr/eval.cc @@ -136,6 +136,7 @@ EvalState::EvalState() , sType(symbols.create("type")) , sMeta(symbols.create("meta")) , sName(symbols.create("name")) + , sValue(symbols.create("value")) , sSystem(symbols.create("system")) , sOverrides(symbols.create("__overrides")) , sOutputs(symbols.create("outputs")) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index b896137a69..cac8af8770 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -93,7 +93,7 @@ class EvalState public: SymbolTable symbols; - const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, + const Symbol sWith, sOutPath, sDrvPath, sType, sMeta, sName, sValue, sSystem, sOverrides, sOutputs, sOutputName, sIgnoreNulls; Symbol sDerivationNix; diff --git a/src/libexpr/primops.cc b/src/libexpr/primops.cc index cfd669d26c..214bf8b999 100644 --- a/src/libexpr/primops.cc +++ b/src/libexpr/primops.cc @@ -277,10 +277,10 @@ static void prim_tryEval(EvalState & state, Value * * args, Value & v) state.mkAttrs(v, 2); try { state.forceValue(*args[0]); - v.attrs->push_back(Attr(state.symbols.create("value"), args[0])); + v.attrs->push_back(Attr(state.sValue, args[0])); mkBool(*state.allocAttr(v, state.symbols.create("success")), true); } catch (AssertionError & e) { - mkBool(*state.allocAttr(v, state.symbols.create("value")), false); + mkBool(*state.allocAttr(v, state.sValue), false); mkBool(*state.allocAttr(v, state.symbols.create("success")), false); } v.attrs->sort(); @@ -810,7 +810,8 @@ static void prim_removeAttrs(EvalState & state, Value * * args, Value & v) /* Builds a set from a list specifying (name, value) pairs. To be precise, a list [{name = "name1"; value = value1;} ... {name = "nameN"; value = valueN;}] is transformed to {name1 = value1; - ... nameN = valueN;}. */ + ... nameN = valueN;}. In case of duplicate occurences of the same + name, the first takes precedence. */ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) { state.forceList(*args[0]); @@ -828,16 +829,15 @@ static void prim_listToAttrs(EvalState & state, Value * * args, Value & v) throw TypeError("`name' attribute missing in a call to `listToAttrs'"); string name = state.forceStringNoCtx(*j->value); - Bindings::iterator j2 = v2.attrs->find(state.symbols.create("value")); - if (j2 == v2.attrs->end()) - throw TypeError("`value' attribute missing in a call to `listToAttrs'"); - Symbol sym = state.symbols.create(name); if (seen.find(sym) == seen.end()) { + Bindings::iterator j2 = v2.attrs->find(state.symbols.create(state.sValue)); + if (j2 == v2.attrs->end()) + throw TypeError("`value' attribute missing in a call to `listToAttrs'"); + v.attrs->push_back(Attr(sym, j2->value, j2->pos)); seen.insert(sym); } - /* !!! Throw an error if `name' already exists? */ } v.attrs->sort();