diff options
Diffstat (limited to 'third_party/nix/src/libexpr')
-rw-r--r-- | third_party/nix/src/libexpr/eval.cc | 25 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/nixexpr.cc | 22 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/nixexpr.hh | 8 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/parser.y | 57 | ||||
-rw-r--r-- | third_party/nix/src/libexpr/symbol-table.hh | 2 |
5 files changed, 64 insertions, 50 deletions
diff --git a/third_party/nix/src/libexpr/eval.cc b/third_party/nix/src/libexpr/eval.cc index 6d77928d7d4f..6df7e66b6542 100644 --- a/third_party/nix/src/libexpr/eval.cc +++ b/third_party/nix/src/libexpr/eval.cc @@ -6,6 +6,7 @@ #include <fstream> #include <iostream> #include <new> +#include <variant> #include <absl/strings/match.h> #include <gc/gc.h> @@ -24,6 +25,7 @@ #include "libutil/hash.hh" #include "libutil/json.hh" #include "libutil/util.hh" +#include "libutil/visitor.hh" namespace nix { @@ -185,13 +187,15 @@ static void* oomHandler(size_t requested) { #endif static Symbol getName(const AttrName& name, EvalState& state, Env& env) { - if (name.symbol.set()) { - return name.symbol; - } - Value nameValue; - name.expr->eval(state, env, nameValue); - state.forceStringNoCtx(nameValue); - return state.symbols.Create(nameValue.string.s); + return std::visit( + util::overloaded{[&](const Symbol& name) -> Symbol { return name; }, + [&](Expr* expr) -> Symbol { + Value nameValue; + expr->eval(state, env, nameValue); + state.forceStringNoCtx(nameValue); + return state.symbols.Create(nameValue.string.s); + }}, + name); } static bool gcInitialised = false; @@ -890,12 +894,7 @@ static std::string showAttrPath(EvalState& state, Env& env, } else { first = false; } - try { - out << getName(i, state, env); - } catch (Error& e) { - assert(!i.symbol.set()); - out << "\"${" << *i.expr << "}\""; - } + out << getName(i, state, env); } return out.str(); } diff --git a/third_party/nix/src/libexpr/nixexpr.cc b/third_party/nix/src/libexpr/nixexpr.cc index 28d8eee7a7f8..2de37f50e9b9 100644 --- a/third_party/nix/src/libexpr/nixexpr.cc +++ b/third_party/nix/src/libexpr/nixexpr.cc @@ -1,9 +1,11 @@ #include "libexpr/nixexpr.hh" #include <cstdlib> +#include <variant> #include "libstore/derivations.hh" #include "libutil/util.hh" +#include "libutil/visitor.hh" namespace nix { @@ -198,17 +200,17 @@ std::ostream& operator<<(std::ostream& str, const Pos& pos) { std::string showAttrPath(const AttrPath& attrPath) { std::ostringstream out; bool first = true; - for (auto& i : attrPath) { + for (auto& attr : attrPath) { if (!first) { out << '.'; } else { first = false; } - if (i.symbol.set()) { - out << i.symbol; - } else { - out << "\"${" << *i.expr << "}\""; - } + + std::visit(util::overloaded{ + [&](const Symbol& sym) { out << sym; }, + [&](const Expr* expr) { out << "\"${" << *expr << "}\""; }}, + attr); } return out.str(); } @@ -268,8 +270,8 @@ void ExprSelect::bindVars(const StaticEnv& env) { def->bindVars(env); } for (auto& i : attrPath) { - if (!i.symbol.set()) { - i.expr->bindVars(env); + if (auto* expr = std::get_if<Expr*>(&i)) { + (*expr)->bindVars(env); } } } @@ -277,8 +279,8 @@ void ExprSelect::bindVars(const StaticEnv& env) { void ExprOpHasAttr::bindVars(const StaticEnv& env) { e->bindVars(env); for (auto& i : attrPath) { - if (!i.symbol.set()) { - i.expr->bindVars(env); + if (auto* expr = std::get_if<Expr*>(&i)) { + (*expr)->bindVars(env); } } } diff --git a/third_party/nix/src/libexpr/nixexpr.hh b/third_party/nix/src/libexpr/nixexpr.hh index 0bf5245181ec..7ec6f7f17f39 100644 --- a/third_party/nix/src/libexpr/nixexpr.hh +++ b/third_party/nix/src/libexpr/nixexpr.hh @@ -1,6 +1,7 @@ #pragma once #include <map> +#include <variant> #include "libexpr/symbol-table.hh" #include "libexpr/value.hh" @@ -60,12 +61,7 @@ class EvalState; struct StaticEnv; /* An attribute path is a sequence of attribute names. */ -struct AttrName { - Symbol symbol; - Expr* expr; - AttrName(const Symbol& s) : symbol(s){}; - AttrName(Expr* e) : expr(e){}; -}; +using AttrName = std::variant<Symbol, Expr*>; typedef std::vector<AttrName> AttrPath; diff --git a/third_party/nix/src/libexpr/parser.y b/third_party/nix/src/libexpr/parser.y index fe8759f3c6b7..eb3f92db7844 100644 --- a/third_party/nix/src/libexpr/parser.y +++ b/third_party/nix/src/libexpr/parser.y @@ -16,6 +16,7 @@ #ifndef BISON_HEADER #define BISON_HEADER +#include <variant> #include "libutil/util.hh" #include "libexpr/nixexpr.hh" #include "libexpr/eval.hh" @@ -84,30 +85,39 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, // Checking attrPath validity. // =========================== for (i = attrPath.begin(); i + 1 < attrPath.end(); i++) { - if (i->symbol.set()) { - ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol); + if (const auto* sym = std::get_if<Symbol>(&(*i)); sym && sym->set()) { + ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(*sym); if (j != attrs->attrs.end()) { if (!j->second.inherited) { ExprAttrs * attrs2 = dynamic_cast<ExprAttrs *>(j->second.e); if (!attrs2) { dupAttr(attrPath, pos, j->second.pos); } attrs = attrs2; - } else + } else { dupAttr(attrPath, pos, j->second.pos); + } } else { - ExprAttrs * nested = new ExprAttrs; - attrs->attrs[i->symbol] = ExprAttrs::AttrDef(nested, pos); + ExprAttrs* nested = new ExprAttrs; + attrs->attrs[*sym] = ExprAttrs::AttrDef(nested, pos); attrs = nested; } } else { - ExprAttrs *nested = new ExprAttrs; - attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, nested, pos)); - attrs = nested; + // Yes, this code does not handle all conditions + // exhaustively. We use std::get to throw if the condition + // that isn't covered happens, which is potentially a + // behaviour change from the previous default constructed + // Symbol. It should alert us about anything untoward going + // on here. + auto* expr = std::get<Expr*>(*i); + + ExprAttrs *nested = new ExprAttrs; + attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(expr, nested, pos)); + attrs = nested; } } // Expr insertion. // ========================== - if (i->symbol.set()) { - ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(i->symbol); + if (auto* sym = std::get_if<Symbol>(&(*i)); sym && sym->set()) { + ExprAttrs::AttrDefs::iterator j = attrs->attrs.find(*sym); if (j != attrs->attrs.end()) { // This attr path is already defined. However, if both // e and the expr pointed by the attr path are two attribute sets, @@ -118,8 +128,9 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, if (jAttrs && ae) { for (auto & ad : ae->attrs) { auto j2 = jAttrs->attrs.find(ad.first); - if (j2 != jAttrs->attrs.end()) // Attr already defined in iAttrs, error. + if (j2 != jAttrs->attrs.end()) {// Attr already defined in iAttrs, error. dupAttr(ad.first, j2->second.pos, ad.second.pos); + } jAttrs->attrs[ad.first] = ad.second; } } else { @@ -127,11 +138,13 @@ static void addAttr(ExprAttrs * attrs, AttrPath & attrPath, } } else { // This attr path is not defined. Let's create it. - attrs->attrs[i->symbol] = ExprAttrs::AttrDef(e, pos); - e->setName(i->symbol); + attrs->attrs[*sym] = ExprAttrs::AttrDef(e, pos); + e->setName(*sym); } } else { - attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(i->expr, e, pos)); + // Same caveat as the identical line above. + auto* expr = std::get<Expr*>(*i); + attrs->dynamicAttrs.push_back(ExprAttrs::DynamicAttrDef(expr, e, pos)); } } @@ -444,19 +457,23 @@ binds | binds INHERIT attrs ';' { $$ = $1; for (auto & i : *$3) { - if ($$->attrs.find(i.symbol) != $$->attrs.end()) - dupAttr(i.symbol, makeCurPos(@3, data), $$->attrs[i.symbol].pos); + auto sym = std::get<Symbol>(i); + if ($$->attrs.find(sym) != $$->attrs.end()) { + dupAttr(sym, makeCurPos(@3, data), $$->attrs[sym].pos); + } Pos pos = makeCurPos(@3, data); - $$->attrs[i.symbol] = ExprAttrs::AttrDef(new ExprVar(CUR_POS, i.symbol), pos, true); + $$->attrs[sym] = ExprAttrs::AttrDef(new ExprVar(CUR_POS, sym), pos, true); } } | binds INHERIT '(' expr ')' attrs ';' { $$ = $1; /* !!! Should ensure sharing of the expression in $4. */ for (auto & i : *$6) { - if ($$->attrs.find(i.symbol) != $$->attrs.end()) - dupAttr(i.symbol, makeCurPos(@6, data), $$->attrs[i.symbol].pos); - $$->attrs[i.symbol] = ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, i.symbol), makeCurPos(@6, data)); + auto sym = std::get<Symbol>(i); + if ($$->attrs.find(sym) != $$->attrs.end()) { + dupAttr(sym, makeCurPos(@6, data), $$->attrs[sym].pos); + } + $$->attrs[sym] = ExprAttrs::AttrDef(new ExprSelect(CUR_POS, $4, sym), makeCurPos(@6, data)); } } | { $$ = new ExprAttrs; } diff --git a/third_party/nix/src/libexpr/symbol-table.hh b/third_party/nix/src/libexpr/symbol-table.hh index c4c1163bed15..efc2314b75e8 100644 --- a/third_party/nix/src/libexpr/symbol-table.hh +++ b/third_party/nix/src/libexpr/symbol-table.hh @@ -21,7 +21,7 @@ class Symbol { bool operator<(const Symbol& s2) const { return *s < *s2.s; } - operator const std::string&() const { return *s; } + operator const std::string &() const { return *s; } bool set() const { return s; } |