I’ve encountered unexpected behavior when using custom struct with List and Dict. I’m not sure if this is expected behavior or a bug, but the __moveinit__ method is called twice when used with a Dict, but only once with a List. Here’s the code
Maybe this is because in List.append() the item gets directly moved into the List while in Dict.__setitem__() it is first moved into a DictEntry which is then moved into the Dict.
Great catch. This appears to be because of how dict is layered with DictEntry, from dict.mojo:
fn _insert(mut self, owned key: K, owned value: V):
self._insert(DictEntry[K, V](key^, value^)) ### MOVE V into DictEntry
fn _insert[
safe_context: Bool = False
](mut self, owned entry: DictEntry[K, V]):
@parameter
if not safe_context:
self._maybe_resize()
var found, slot, index = self._find_index(entry.hash, entry.key)
self._entries[index] = entry^ # MOVE DictEntry (and elements) into storage.
Someone could optimize this extra move away by making these a little more clever, e.g. make the first one the canonical insert. It’s unclear to me why anyone should be inserting DictEntry directly anyway.