[Pre-RFC] Split IndexMut into IndexMut and IndexAssign

Summary

The IndexMut trait isn’t suitable for python-like assignment of dictionary elements; this can be changed by adding an IndexAssign trait defined something like this:

pub trait IndexAssign<Idx> {
    type Value;
    fn index_assign(&mut self, idx: Idx, value: Self::Value);
}

impl<C, Idx> IndexAssign<Idx> for C
where
    C: IndexMut<Idx>,
    C::Output: Sized,
{
    type Value = C::Output;

    fn index_assign(&mut self, idx: Idx, value: Self::Value) {
        *self.index_mut(idx) = value;
    }
}

Detailed Description

In the exact case of container[key] = value, the code would desugar to container.index_assign(key, value), instead of *container.index_mut(key) = value.

Backwards Compatibility

This behavior is backwards compatible with existing code that only implements IndexMut, because internally the default implementation for cases where assignment is possible is the same behavior as before. The following related statements will be unaffected:

  • container[key] += value
  • container[key] -= value
  • container[key] *= value
  • container[key] /= value
  • container[key] |= value
  • container[key] &= value
  • container[key] ^= value
  • container[key] <<= value
  • container[key] >>= value

Additionally, the blanket impl for IndexAssign prevents existing code from being affected; in the case of objects like Vec<T>, IndexAssign will behave the same; since as it stands right now assignment of unsized types isn’t really possible, the restriction on C::Output: Sized isn’t restrictive.

Advantages

  • Additional level of control for users that opt in
  • APIs to containers can be much more flexible
  • Can currently be implemented without breaking existing code

Drawbacks

  • Additional language complexity
  • Work to implement into compiler

Alternatives

  • None for the desired effect

Edits: Altered suggested implementation to make trait more flexible.

Here’s some prior art – please make sure you’ve read and addressed any past issues noted.

1 Like

Thanks for pointing that out! I’ll close the topic and try to contribute to the discussion in the tracking issue instead.

Err I can’t close the topic but thanks either way!