# Simple Program Rejected with E0506?

**URL:** <https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614>\
**Category:** compiler\
**Created:** [June 23, 2020, 2:55am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614 "2020-06-23T02:55:59Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![DavePearce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/davepearce/32/2666_2.png) [@DavePearce](https://internals.rust-lang.org/u/DavePearce)\
**Post date:** [June 23, 2020, 2:56am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614/1 "2020-06-23T02:56:00Z")

</div>

Hi,

The following program is currently rejected by rustc:

```
fn main() {
  let mut x = Box::new(0); let mut y = Box::new(&mut x); y = Box::new(*y);
}

```

This programs seems to me like it should be fine, since the borrow `&mut x` is simply moved into the new box. I'm wondering whether there is any specific reason this is not allowed?

---

<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:** [June 23, 2020, 4:03am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614/2 "2020-06-23T04:03:20Z")

</div>

Here's a version that works:

```rust
fn main() {
    let mut x = Box::new(0);
    let mut y = Box::new(&mut x);
    y = Box::new(*{y});
}

```

I suspect the reason this happens is _reborrowing_. The above snippet prevents this by explicitly moving from `y` (via a block).

In effect, I believe the compiler is rewriting your code to

```rust
fn main() {
    let mut x = Box::new(0);
    let mut y = Box::new(&mut x);
    y = Box::new(&mut **y);
}

```

This is what allows you to do things such as e.g. pass a `&mut _` variable to a function even though `&mut _` is not `Copy`; the compiler reborrows the mutable borrow and gives the function a new borrow with a shorter lifetime borrowed from yours. (That's a lot of "borrow"...)

(This question may be a better fit on users than internals, as it has nothing to do with development of the language.)

---

<div class="post-metadata">

**Author:** ![DavePearce](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/davepearce/32/2666_2.png) [@DavePearce](https://internals.rust-lang.org/u/DavePearce)\
**Post date:** [June 23, 2020, 4:21am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614/3 "2020-06-23T04:21:19Z")

</div>

Ok, that does make some sense. Basically, it reborrows when it shouldn't. Yes, I've heard of that happening before! Interesting that `*{y}` forces a move.

---

<div class="post-metadata">

**Author:** ![steffahn](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/steffahn/32/13288_2.png) [@steffahn](https://internals.rust-lang.org/u/steffahn)\
**Post date:** [June 23, 2020, 6:37am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614/4 "2020-06-23T06:37:09Z")

</div>

Interesting stuff.. while exploring this kind of behavior I noticed that I can assign a reborrow of a `mut` reference to itself, which doesn’t make sense to me either. What kind of rule is behind this and could it be extended to make the original `Box` example work without the block?

```rust
fn foo(_: &mut Box<i32>) {}

// me trying lots of stuff:
pub fn main() {
    let mut x = Box::new(0);

    // --------------------------
    let mut y: Box<&mut Box<i32>> = Box::new(&mut x);
    // y = Box::new(*y); // doesn’t work
    y = Box::new(*{y}); // but this does
    foo(*y); // advantage: *y doesn’t move anything
    foo(*y);

    // --------------------------
    let mut z = &mut x;
    z = z; // compiler figures not to reborrow, so that it’s okay?
    foo(z); // doesn’t move anything, because it IS (implicitly) a reborrow
    foo(z);

    // --------------------------
    let mut y1: &mut &mut Box<i32> = &mut &mut x;
    y1 = &mut *y1; // explicit reborrow; why does this work??
                  // (similarly above, z = &mut *z would’ve worked...)
    foo(*y1);
    foo(*y1);
}

```

---

<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:** [September 21, 2020, 6:37am UTC](https://internals.rust-lang.org/t/simple-program-rejected-with-e0506/12614/5 "2020-09-21T06:37:32Z")

</div>

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