# Rust 2030 Christmas list: Inout methods

**URL:** <https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944>\
**Category:** language design\
**Created:** [January 10, 2022, 4:46pm UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944 "2022-01-10T16:46:40Z")\
**Posts on this page:** 7\
**Page:** 2

<div class="post-metadata">

**Author:** ![CAD97](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/cad97/32/3460_2.png) [@CAD97](https://internals.rust-lang.org/u/CAD97)\
**Post date:** [January 19, 2022, 11:31am UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/21 "2022-01-19T11:31:01Z")

</div>

> [@PoignardAzur](#):
>
> use the same monomorphization

Big asterisk on this: they don't, not on the abstract machine, at least. On the abstract machine, there's shadow state (that isn't represented on the physical machine) which is handled differently for shared or unique references: the retag/reborrow operation — in Stacked Borrows (Miri) this is what manages the borrow stack and puts the Shr/Uniq tags into the borrow stack. At an abstract machine level, it truly is two different functions, which may trivially reduce down to the same concrete machine code and be deduplicated.

Lifetimes, however, actually are a purely frontend construct; the abstract machine only cares that references are operationally used in a valid way.

---

<div class="post-metadata">

**Author:** ![mathstuf](https://avatars.discourse-cdn.com/v4/letter/m/958977/32.png) [@mathstuf](https://internals.rust-lang.org/u/mathstuf)\
**Post date:** [January 21, 2022, 12:40pm UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/22 "2022-01-21T12:40:56Z")

</div>

[This post](https://internals.rust-lang.org/t/pre-rfc-revamped-const-trait-impl-aka-rfc-2632/15192/79) gave me the idea that maybe it could be spelled `~mut` instead of `inout`? Instead of `C: constness`, we have `M: mutability` which applies to all `~mut` uses within the function/struct/etc.

I wonder if this would allow one to write `Iter` and `IterMut` impls with a single syntax in some way?

---

<div class="post-metadata">

**Author:** ![troplin](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/troplin/32/1182_2.png) [@troplin](https://internals.rust-lang.org/u/troplin)\
**Post date:** [January 23, 2022, 11:41am UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/23 "2022-01-23T11:41:50Z")

</div>

> [@PoignardAzur](#):
>
> I have to write a lot of methods like `find_child / find_child_mut` that have virtually the same code except the mut version uses `iter_mut` instead of `iter` , so the code duplication is non-trivial.

Why don't you separate the finding from the getting, i.e. return some index/search result type from `find_child` and then implement both `Index` and `IndexMut` for that type?

Similar to how `find`-Methods on arrays usually return an index and not a reference to the element.

---

<div class="post-metadata">

**Author:** ![qm3ster](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/qm3ster/32/4530_2.png) [@qm3ster](https://internals.rust-lang.org/u/qm3ster)\
**Post date:** [January 25, 2022, 5:41pm UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/24 "2022-01-25T17:41:22Z")

</div>

If we're being generic over mutability, maybe we should be generic over ownership as well? :v

```rust
impl<'a, T, const N: usize> Iterator for Iter<&'a Node<T, N>> {
    type Item = &'a T;
    fn next(&mut self) -> Option<Self::Item> {
        let Self(stack) = self;
        stack.pop_front().map(|Node { ch, value }| {
            stack.extend(ch.iter().flat_map(|o| Some(&**o.as_ref()?)));
            value
        })
    }
}
impl<'a, T, const N: usize> Iterator for Iter<&'a mut Node<T, N>> {
    type Item = &'a mut T;
    fn next(&mut self) -> Option<Self::Item> {
        let Self(stack) = self;
        stack.pop_front().map(|Node { ch, value }| {
            stack.extend(ch.iter_mut().flat_map(|o| Some(&mut **o.as_mut()?)));
            value
        })
    }
}
impl<T, const N: usize> Iterator for Iter<Node<T, N>> {
    type Item = T;
    fn next(&mut self) -> Option<Self::Item> {
        let Self(stack) = self;
        stack.pop_front().map(|Node { ch, value }| {
            stack.extend(ch.into_iter().flat_map(|o| Some(*o?)));
            value
        })
    }
}

```

Look at all this duplication! Not to mention the corresponding

```rust
impl<'a, T, const N: usize> IntoIterator for &'a Node<T, N> {
    type Item = <Self::IntoIter as Iterator>::Item;
    type IntoIter = Iter<Self>;
    fn into_iter(self) -> Self::IntoIter {
        Iter(VecDeque::from([self]))
    }
}
impl<'a, T, const N: usize> IntoIterator for &'a mut Node<T, N> {
    type Item = <Self::IntoIter as Iterator>::Item;
    type IntoIter = Iter<Self>;
    fn into_iter(self) -> Self::IntoIter {
        Iter(VecDeque::from([self]))
    }
}
impl<T, const N: usize> IntoIterator for Node<T, N> {
    type Item = <Self::IntoIter as Iterator>::Item;
    type IntoIter = Iter<Self>;
    fn into_iter(self) -> Self::IntoIter {
        Iter(VecDeque::from([self]))
    }
}

```

(This is not a serious proposal. In my experience these cases are annoying, but rare)

---

<div class="post-metadata">

**Author:** ![derekdreery](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/derekdreery/32/2632_2.png) [@derekdreery](https://internals.rust-lang.org/u/derekdreery)\
**Post date:** [February 3, 2022, 9:26am UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/25 "2022-02-03T09:26:33Z")

</div>

> [@qm3ster](#):
>
> This is not a serious proposal. In my experience these cases are annoying, but rare

IME they come up quite often in the builder pattern. I always end up writing methods like...

```rust
impl Thing {
    fn with_foo(mut self, foo: Foo) -> Self {
        self.foo = foo;
        self
    }

    fn set_foo(&mut self, foo: Foo) -> &mut Self {
        self.foo = foo;
        self
    }
}

```

---

<div class="post-metadata">

**Author:** ![PoignardAzur](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/poignardazur/32/6464_2.png) [@PoignardAzur](https://internals.rust-lang.org/u/PoignardAzur)\
**Post date:** [February 17, 2022, 10:47am UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/26 "2022-02-17T10:47:09Z")

</div>

Quick note: in the library I'm currently working on (fork of druid called widget-cruncher), I'm realizing that mutability effects would be less useful than I thought.

That's because, although my code still does a lot of tree visiting and stuff, the code that visits with shared references and the code with mutable references end up being very different, mostly because mutating the widget tree requires propagating changes.

I don't think that means an inout syntax would be useless, but at the very least it wouldn't be useful for my current use-case. I felt it was important to mention that.

---

<div class="post-metadata">

**Author:** ![system](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/system/32/14092_2.png) [@system](https://internals.rust-lang.org/u/system)\
**Post date:** [May 18, 2022, 10:48am UTC](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944/27 "2022-05-18T10:48:03Z")

</div>

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.

[Previous page](https://internals.rust-lang.org/t/rust-2030-christmas-list-inout-methods/15944.md?page=1)
