# Rust syntax for Cell/RefCell

**URL:** <https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714>\
**Category:** language design\
**Created:** [November 15, 2025, 1:37am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714 "2025-11-15T01:37:17Z")\
**Posts on this page:** 17\
**Page:** 2

<div class="post-metadata">

**Author:** ![Vorpal](https://avatars.discourse-cdn.com/v4/letter/v/aca169/32.png) [@Vorpal](https://internals.rust-lang.org/u/Vorpal)\
**Post date:** [November 17, 2025, 11:24pm UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/21 "2025-11-17T23:24:54Z")

</div>

> [@izagawd](#):
>
> you need mut for that syntax

Ah yeah, I see what you mean. If you can't provide that at some level it gets difficult. You could _possibly_ create thin mut handles, that actually contain a shared reference to the real object with interior mutability member(s), but I don't see a way to avoid the extra pointer indirection, which would be bad for performance. It also seems awkward and silly to have to build a parallel shadow hierarchy of objects mirroring the real objects.

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [November 18, 2025, 12:15am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/22 "2025-11-18T00:15:06Z")

</div>

So `DerefMut` is defined with

```rust
    fn deref_mut(&mut self) -> &mut Self::Target;
                 ^^^^

```

But `Cell` is one of a couple types which could implement the trait requiring only `&self`. Under keyword generics (or just with compiler magic) the bound could default to `&mut self` but allow for `&self`.

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 12:59am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/23 "2025-11-18T00:59:06Z")

</div>

I think we need compiler and library support for it to feel ergonomic enough tbh.

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 1:03am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/24 "2025-11-18T01:03:35Z")

</div>

The idea of `Cell` is never providing a direct reference, so I do not think that is the way to go about this. `Cell` being able to be dereffed to a unique reference via a shared reference would lead to undefined behavior.

---

<div class="post-metadata">

**Author:** ![quinedot](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quinedot/32/7294_2.png) [@quinedot](https://internals.rust-lang.org/u/quinedot)\
**Post date:** [November 18, 2025, 1:28am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/25 "2025-11-18T01:28:49Z")

</div>

It could conceivably be a kind of [refinement](https://rust-lang.github.io/rfcs/3245-refined-impls.html) on the implementation of `AddAssign` for `Wrapper`, say.

```rust
impl<T, R> AddAssign<R> for Wrapper<T>
where
    T: Copy + AddAssign<R>,
{
    #[allow(refining_self)]
    fn add_assign(&self, rhs: R) {
        let mut inner = self.0.get();
        inner += rhs;
        self.0.set(inner);
    }
}

```

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 3:50am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/26 "2025-11-18T03:50:13Z")

</div>

I don't see why a trait that represents `AddAssign` for interior mutability cannot be directly implemented by `Cell<T: Copy>`. Could be called `InteriorAddAssign`

---

<div class="post-metadata">

**Author:** ![quaternic](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quaternic/32/10440_2.png) [@quaternic](https://internals.rust-lang.org/u/quaternic)\
**Post date:** [November 18, 2025, 4:26am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/27 "2025-11-18T04:26:54Z")

</div>

This has its own major ergonomic issues, but it is possible to implement `AddAssign` for shared references to a wrapped cell:

```rust
struct Counter(Cell<i32>);

impl AddAssign<i32> for &Counter {
    fn add_assign(&mut self, x: i32) {
        self.0.set(self.0.get() + x);
    }
}

fn foo(mut x: &Counter, ys: &[Counter]) {
    x += 1;
    for mut y in ys {
        y += 10;
    }
}

```

Unfortunately, this requires you to have a mutable place with the `&Counter` in it, so e.g. incrementing a field hits issues:

```rust
struct Container(Counter);
let x: &Container = ...
// These don't compile:
x.0 += 1;
&x.0 += 1;
// These do, but aren't exactly pretty:
*&mut &x.0 += 1;
{ let mut a = &x.0; a += 1; }
(&x.0).add_assign(1);

```

[playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2024&gist=38363483d45e1a9ca9aa34db4ff34cde)

* * *

That makes me think maybe the `OpAssign`-traits should have also taken self by value, and would typically be implemented for `&mut Type` (instead of `Type` as currently). That could have allowed implementations for `&MyInteriorMutType` and `MyCustomMutRef` as well.

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 7:29am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/28 "2025-11-18T07:29:32Z")

</div>

I am assuming the reason why `OpAssign` traits take a reference rather than a value, is to enable situations like this

```rust
let a : i32 = 4;
a += 4;

```

had `AddAssign` worked with `i32` as its receiver rather than `&mut i32`, this won't be possible.

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 7:56am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/29 "2025-11-18T07:56:11Z")

</div>

ive been thinking maybe `+=`/`-=` could also be used for interior mut operations. the compiler just checks if it implements `InteriorAddAssign` or `AddAssign`

There could be something like

```rust
trait InteriorAddAssign : AddAssign{}

```

and it would kinda work like how Fn/FnMut/FnOnce works, where doing `some_fn()` calls `Fn`, or `FnMut`, or `FnOnce`, depending on the context.

What does everyone think?

---

<div class="post-metadata">

**Author:** ![quaternic](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/quaternic/32/10440_2.png) [@quaternic](https://internals.rust-lang.org/u/quaternic)\
**Post date:** [November 18, 2025, 10:46pm UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/30 "2025-11-18T22:46:13Z")

</div>

I meant

```rust
trait AddAssign<Rhs> {
    fn add_assing(self, rhs: Rhs);
}

// typical impl
impl AddAssign<i32> for &mut i32 {
    fn add_assing(self, rhs: i32) {
        *self = *self + rhs;
    }
}

```

That is, the method takes `Self = &mut i32` by value.

However, this would also require the syntax to be able to auto-reference to allow

```rust
let mut a: i32 = 0;
a += 1;

```

I assume there are good reasons for the current design.

* * *

That signature is in fact much like those for the non-assign operators, so you _could_ use `+` as a substitute for `+=`:

```rust
struct Counter(Cell<i32>);
impl std::ops::Add<i32> for &Counter {
    type Output = ();
    fn add(self, rhs: i32) {
        self.0.set(self.0.get() + rhs);
    }
}

fn main() {
    let c = Counter(Cell::new(0));
    &c + 1;
    &c + 10;
    assert_eq!(c.0.get(), 11);
}

```

(I don't recommend doing so for real code, though it might be useful for demonstrating the difference `+=` on shared references could make)

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 18, 2025, 11:59pm UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/31 "2025-11-18T23:59:53Z")

</div>

Today `a += b` is pretty much `AddAssign::add_assign(&mut a, b);` If `AddAssign` instead took `self` by value and was implemented for `&mut T`, the compiler would need special rules for `&mut T` to accept `T` on the left-hand side.

I believe it was the right design decision for rust to make `add_assign` take a reference to `self` rather than `self` itself

---

<div class="post-metadata">

**Author:** ![toc](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/toc/32/6692_2.png) [@toc](https://internals.rust-lang.org/u/toc)\
**Post date:** [November 19, 2025, 1:38am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/32 "2025-11-19T01:38:09Z")

</div>

> [@izagawd](#):
>
> `Cell` being able to be dereffed to a unique reference via a shared reference would lead to undefined behavior.

`Cell<T>` dereffing to `&mut T` certainly would, and maybe that means the trait is inapplicable. But possibly it could deref to a place (unless I'm misusing that). In any case

```rust
// we could enable these
*cell += 4;
let k: i64 = *cell * 17;
// without enabling this
let i: &mut i64 = &*cell;

```

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 19, 2025, 2:02am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/33 "2025-11-19T02:02:45Z")

</div>

My suggestion already covers that. A type can implement a trait and they get the operator syntax. It will enable other types, not just `Cell`, to opt into the syntax. For example:

```rust
struct Foo{
    one: Cell<i32>,
    two: Cell<i32>
}
impl<T: Copy> InteriorAddAssign<T> for Cell<T> where T: AddAssign<T> {
    fn interior_add_assign(&self, other: T) {
        self.update(|mut x| {x += other; x } )
    }
}
impl InteriorAddAssign for Foo {
    fn interior_add_assign(&self, other: Self) {
        self.one += ^other.one; // ^ being syntax to get T from Cell<T: Copy>. But I'm not 100% for it. but I would like something that does this though
        self.two += ^other.two;
    }
}
let foo : &Foo = &Foo::new();
let other_foo = Foo::new();

foo += other_foo; // += with Foo now valid syntax

```

I also proposed `:=` syntax that can be opted in, and intend for Cell to implement it with `cell.set(..)`, and `RefCell<T>` to implement it with `*refcell.borrow_mut() = something`

---

<div class="post-metadata">

**Author:** ![SkiFire13](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/skifire13/32/7579_2.png) [@SkiFire13](https://internals.rust-lang.org/u/SkiFire13)\
**Post date:** [November 19, 2025, 7:05am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/34 "2025-11-19T07:05:15Z")

</div>

> [@toc](#):
>
> `Cell<T>` dereffing to `&mut T` certainly would, and maybe that means the trait is inapplicable. But possibly it could deref to a place (unless I'm misusing that). In any case

A place is not a type, so `DerefMut` cannot deref to a place. What generally happens is that `DerefMut` returns a mutable reference, and the compiler automatically adds another dereference operator to create a mutable place from that.

Getting a place for `T` from a `&Cell<T>` would be unsound anyway because you can always reborrow a place to create a new reference. You would need a new kind of place for `Cell`s only (edit: and even then `*cell += 1;` would not be totally ok because it would temporarily create a mutable reference).

---

<div class="post-metadata">

**Author:** ![kpreid](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/kpreid/32/8484_2.png) [@kpreid](https://internals.rust-lang.org/u/kpreid)\
**Post date:** [November 19, 2025, 7:33am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/35 "2025-11-19T07:33:39Z")

</div>

> [@SkiFire13](#):
>
> Getting a place for `T` from a `&Cell<T>` would be unsound anyway because you can always reborrow a place to create a new reference. You would need a new kind of place for `Cell`s only

The language does already contain places that cannot be referenced: unaligned fields in `#[repr(packed)]` structs.

---

<div class="post-metadata">

**Author:** ![izagawd](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/izagawd/32/12748_2.png) [@izagawd](https://internals.rust-lang.org/u/izagawd)\
**Post date:** [November 19, 2025, 7:29pm UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/36 "2025-11-19T19:29:14Z")

</div>

What I’ve been trying to explore is a trait+syntax approach where users implement an interior mut operator trait for their interior mut type, and then operation with that interior mut type look syntactically light. So far, nobody has really engaged with that direction directly. I haven’t seen any counter arguments/supporting arguments to that. There's mostly been suggestions that are still pretty syntactically heavy IMO

This matters in codebases and libraries where interior mutability is the dominant pattern (e.g. GUI frameworks like leptos, dioxus, and gtk-rs, and certain game/engine styles) and most state sits behind `Cell`-like types. In those contexts, the difference between `x += 1` and `x.update(|x| x + 1)` or `*x.pawn() += 1` is amplified across thousands of call sites, and the boilerplate may accumulate and make syntax look a bit ugly

I’m not married to the exact syntax or trait names. The core question I’m interested in is whether a _language-level_, trait-based integration between interior-mut types and operators is something acceptable/unacceptable, or whether there’s a version of that idea that could be acceptable.

Discussion in that direction itself would be very helpful.

---

<div class="post-metadata">

**Author:** ![Ddystopia](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/ddystopia/32/10915_2.png) [@Ddystopia](https://internals.rust-lang.org/u/Ddystopia)\
**Post date:** [November 20, 2025, 9:35am UTC](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714/37 "2025-11-20T09:35:48Z")

</div>

My biggest problem with Cell is that I generally can't use all those utilities available for usual primitive numbers. My concern is directly connected to [Improving usability of having many nearly-identical methods - #10 by Vorpal](https://internals.rust-lang.org/t/improving-usability-of-having-many-nearly-identical-methods/23712/10) , as it is a general pattern in Rust - when something is not ergonomic, we will just manually add methods to make something easier. And sometimes something gets missed, like `Cell`.

Thus, language support for Cell would help Cell and I would be glad about it.

[Previous page](https://internals.rust-lang.org/t/rust-syntax-for-cell-refcell/23714.md?page=1)
