fix(3p/nix/libexpr): Do not allow duplicate attribute insertion

This is closer to bug-for-bug compatibility with the previous version,
which would put new elements at the end of the array and (due to the
linear scan) return previous ones.
This commit is contained in:
Vincent Ambo 2020-05-22 20:29:02 +01:00
parent c08886ab82
commit c25281820f

View file

@ -4,15 +4,29 @@
#include <absl/container/btree_map.h> #include <absl/container/btree_map.h>
#include <gc/gc_cpp.h> #include <gc/gc_cpp.h>
#include <glog/logging.h>
#include "eval-inline.hh" #include "eval-inline.hh"
namespace nix { namespace nix {
// TODO: using insert_or_assign might break existing Nix code because // This function inherits its name from previous implementations, in
// of the weird ordering situation. Need to investigate. // which Bindings was backed by an array of elements which was scanned
// linearly.
//
// In that setup, inserting duplicate elements would always yield the
// first element (until the next sort, which wasn't stable, after
// which things are more or less undefined).
//
// This behaviour is mimicked by using .insert(), which will *not*
// override existing values.
void Bindings::push_back(const Attr& attr) { void Bindings::push_back(const Attr& attr) {
attributes_.insert_or_assign(attr.name, attr); auto [_, inserted] = attributes_.insert_or_assign(attr.name, attr);
if (!inserted) {
DLOG(WARNING) << "attempted to insert duplicate attribute for key '"
<< attr.name << "'";
}
} }
size_t Bindings::size() { return attributes_.size(); } size_t Bindings::size() { return attributes_.size(); }