in starlark/src/stdlib/dict.rs [305:340]
fn update(this: Value, ref pairs: Option<Value>, kwargs: DictRef) -> anyhow::Result<NoneType> {
let pairs = if pairs.map(|x| x.ptr_eq(this)) == Some(true) {
// someone has done `x.update(x)` - that isn't illegal, but we will have issues
// with trying to iterate over x while holding x for mutation, and it doesn't do
// anything useful, so just change pairs back to None
None
} else {
pairs
};
let mut this = Dict::from_value_mut(this)?.unwrap();
if let Some(pairs) = pairs {
if let Some(dict) = Dict::from_value(pairs) {
for (k, v) in dict.iter_hashed() {
this.insert_hashed(k, v);
}
} else {
for v in pairs.iterate(heap)? {
let mut it = v.iterate(heap)?;
let k = it.next();
let v = if k.is_some() { it.next() } else { None };
if unlikely(v.is_none() || it.next().is_some()) {
return Err(anyhow!(
"dict.update expect a list of pairs or a dictionary as first argument, got a list of non-pairs.",
));
};
this.insert_hashed(k.unwrap().get_hashed()?, v.unwrap());
}
}
}
for (k, v) in kwargs.iter_hashed() {
this.insert_hashed(k, v);
}
Ok(NoneType)
}