# \`with\` clauses

**URL:** <https://internals.rust-lang.org/t/with-clauses/15761>\
**Category:** language design\
**Created:** [December 9, 2021, 8:54pm UTC](https://internals.rust-lang.org/t/with-clauses/15761 "2021-12-09T20:54:06Z")\
**Posts on this page:** 1\
**Showing post:** 8

<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:** [December 11, 2021, 9:46am UTC](https://internals.rust-lang.org/t/with-clauses/15761/8 "2021-12-11T09:46:03Z")

</div>

This desugaring doesn't feel right:

- What are `get_arg()` and `Arg` here?
- How did the `&self` parameter become `&mut self`? This is unsound in presence of code that calls `visit` while expecting it to take an `&self`.

```rust
// `Foo`'s definition is valid today, so it has to compile
trait Foo {
    fn foo(&self);
    fn bar(&self, f: impl Fn());
    fn baz(&self) {
        // This is possible only because both `bar` and `foo` take `&self`.
        self.bar(|| self.foo())
    }
}

impl Foo for MyNode
with(ob: &mut Option<Box<i32>>)
{
    fn foo(&self) {
        *ob = None; // Invalidates any reference to the inside of `ob`
    }
    fn bar(&self, f: impl Fn()) {
        // Let's assume that the box is valid now
        let box_ref: &Box<i32> = ob.as_ref().unwrap();
        f(); // This calls `self.foo()` which invalidates `box_ref`
        println!("{}", box_ref); // Oops, now we're printing invalid data
    }
}

fn main() {
    with(cx: &mut Some(Box::new(0)) {
        MyNode.baz();
    }
}

```

---

_[View the full topic](https://internals.rust-lang.org/t/with-clauses/15761)._
