# Pre-RFC: Move-or-borrow elision

**URL:** https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181
**Category:** language design
**Created:** [October 9, 2020, 10:14am UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181 "2020-10-09T10:14:52Z")
**Posts on this page:** 9
**Page:** 2

<div class="post-metadata">

### Author: ![H2CO3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/h2co3/32/2849_2.png) [@H2CO3](https://internals.rust-lang.org/u/H2CO3)
#### Post date: [October 13, 2020, 7:09pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/21 "2020-10-13T19:09:12Z")

</div>

However, in the post, there's also:

> Since this design work was in a spirit of direct contradiction to Rust’s goals, it’s hard to see it having a big impact on the design of Rust.

And in the [original IRLO thread](https://internals.rust-lang.org/t/notes-on-a-smaller-rust/13147), he even mentions as well that:

> This post is not to propose any change to Rust (even my brief discussion of "Autoclone" at the end I'm not very interested in talking about further now).

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [October 13, 2020, 7:22pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/22 "2020-10-13T19:22:15Z")

</div>

So, I'm not sure whether this is a good idea – for multiple reasons – but I figure we might as well discuss it as an option:

What if _Clone_ implementations could have an attribute indicating that the call can be replaced by a move if the object is cloned and then immediately dropped? Then, the initial function could call `.clone()` consistently (even on the last usage), and still have the code be optimized the way you would hope for.

---

<div class="post-metadata">

### Author: ![bill\_myers](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/bill_myers/32/4085_2.png) [@bill\_myers](https://internals.rust-lang.org/u/bill_myers)
#### Post date: [October 14, 2020, 10:59am UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/23 "2020-10-14T10:59:11Z")

</div>

I'd consider an attribute instead if this is deemed desirable:

```rust
fn func() {
  #[autoclone(Rc)] {
    let x = Rc::new(42);
    foo(x);
    bar(x);
    baz(x);
  }
}

```

The attribute would make the compiler behave in the block as if the types named were copyable, where the copy is performed by calling clone() instead of memcpy. The attribute could be applied to any block, function or item that can have expressions as a descendant.

The advantage of this is that the code looks like code that uses Copy types, and it's clear what code (the clone method on the named types) is being implicitly called, plus you can just apply this to the whole crate if you want a "simpler language".

---

<div class="post-metadata">

### Author: ![SOF3](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/sof3/32/5346_2.png) [@SOF3](https://internals.rust-lang.org/u/SOF3)
#### Post date: [October 14, 2020, 11:04am UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/24 "2020-10-14T11:04:47Z")

</div>

Doubt that is a good idea since it's even more implicit. Also the block where x is used may not always be packed together, and might be mixed with other stuff.

---

<div class="post-metadata">

### Author: ![illicitonion](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/illicitonion/32/3886_2.png) [@illicitonion](https://internals.rust-lang.org/u/illicitonion)
#### Post date: [October 14, 2020, 8:33pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/25 "2020-10-14T20:33:00Z")

</div>

I proposed something very similar [here](https://internals.rust-lang.org/t/idea-improving-the-ergonomics-when-using-rc/9293/74) which had some discussion...

FWIW my desire for this feature mostly stemmed from the pre-`async`/`await` days, where I frequently needed to clone things into `Future` combinator closures, and has mostly gone away since we can now properly borrow into `async` functions. I'm curious about what use-cases others are seeing the frequent need to clone smart pointers into - maybe there are themes that could drive other solutions?

---

<div class="post-metadata">

### Author: ![nakacristo](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/nakacristo/32/10249_2.png) [@nakacristo](https://internals.rust-lang.org/u/nakacristo)
#### Post date: [October 15, 2020, 2:55pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/26 "2020-10-15T14:55:32Z")

</div>

I found a silly way to implement these `move` or `clone`.

> **[Rust Playground](https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=1c5e4131dee8e544d6eac8a82d1f7522)**

If we tolerate to rebind the variable in each call and we put a `drop::<special_thing>(variable)` at the end of the scope, then we can use type inference to write the same in each of the calls. You can see in the example that there are three `foo` calls, but only occur two `clone`s.

---

<div class="post-metadata">

### Author: ![elidupree](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/elidupree/32/4304_2.png) [@elidupree](https://internals.rust-lang.org/u/elidupree)
#### Post date: [October 15, 2020, 4:20pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/27 "2020-10-15T16:20:26Z")

</div>

That's a beautiful, terrible hack! I love it.

Pity the rebinding requirement means it can't be used in loops --

-- hang on, the status quo is that you can't optimize the last clone out of a loop anyway, without adding explicit logic.

That might be a small argument in favor of adding something to support this on the language level. It would allow the compiler to (sometimes) optimize away the last clone in a loop, without additional work by the programmer.

---

<div class="post-metadata">

### Author: ![scottmcm](https://sea2.discourse-cdn.com/flex002/user_avatar/internals.rust-lang.org/scottmcm/32/2355_2.png) [@scottmcm](https://internals.rust-lang.org/u/scottmcm)
#### Post date: [October 15, 2020, 4:41pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/28 "2020-10-15T16:41:23Z")

</div>

> [@elidupree](#):
>
> It would allow the compiler to (sometimes) optimize away the last clone in a loop, without additional work by the programmer.

In general this would be very hard, because the vast majority of the time there's no way for the compiler to know that a particular iteration of a loop is the last one.

The library codes it manually in a few places, such as this in `Vec`:

> <https://github.com/rust-lang/rust/blob/7f587168102498a488abf608a86c7fdfa62fb7bb/library/alloc/src/vec.rs#L1656-L1664>

---

<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: [January 13, 2021, 4:41pm UTC](https://internals.rust-lang.org/t/pre-rfc-move-or-borrow-elision/13181/29 "2021-01-13T16:41:38Z")

</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/pre-rfc-move-or-borrow-elision/13181.md?page=1)
