Skip to content

Commit

Permalink
Add borrowck 6
Browse files Browse the repository at this point in the history
It's a fairly easy one, but interesting nevertheless.
  • Loading branch information
Nilstrieb committed May 14, 2024
1 parent 0c177ff commit 0dbb101
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 0 deletions.
20 changes: 20 additions & 0 deletions code/examples/borrowck_6.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
type R1<'a> = &'a mut i32;
struct R2<'a>(&'a mut i32);

fn r1_once(_: R1){}
fn r2_once(_: R2){}

pub fn r1_twice(x: R1) {
r1_once(x);
r1_once(x);
}

pub fn r2_twice(x: R2) {
r2_once(x);
r2_once(x);
}

fn main() {
r1_twice(&mut 0);
r2_twice(R2(&mut 0));
}
20 changes: 20 additions & 0 deletions code/examples/stderr/borrowck_6.stderr
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
error[E0382]: use of moved value: `x`
--> examples/borrowck_6.rs:14:13
|
12 | pub fn r2_twice(x: R2) {
| - move occurs because `x` has type `R2<'_>`, which does not implement the `Copy` trait
13 | r2_once(x);
| - value moved here
14 | r2_once(x);
| ^ value used here after move
|
note: consider changing this parameter type in function `r2_once` to borrow instead if owning the value isn't necessary
--> examples/borrowck_6.rs:5:15
|
5 | fn r2_once(_: R2){}
| ------- ^^ this parameter takes ownership of the value
| |
| in this function

For more information about this error, try `rustc --explain E0382`.
error: could not compile `code` (example "borrowck_6") due to 1 previous error
1 change: 1 addition & 0 deletions src/SUMMARY.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,4 @@
- [Borrow Checker 3](./borrowck/3.md)
- [Borrow Checker 4](./borrowck/4.md)
- [Borrow Checker 5](./borrowck/5.md)
- [Borrow Checker 6](./borrowck/6.md)
22 changes: 22 additions & 0 deletions src/borrowck/6.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Borrowck 6 @adotinthevoid @Nilstrieb

{{#include ../include/quiz-is-wip.md}}

```rust
{{#include ../../code/examples/borrowck_6.rs}}
```

<details>
<summary>Solution</summary>

```
{{#include ../../code/examples/stderr/borrowck_6.stderr}}
```

`r2_twice` does not compile because `R2` does not implement `Copy`, and is moved twice.
This is basic Rust, but `r1_twice` *does* compile even though `&mut i32` does *not* implement `Copy`!
That's because for `R1`, the reference is not moved into `r1_once`, it is instead *reborrowed*.
Reborrows are a special operation on references that the borrow checker understands and behave like `&mut *x`.
So there is just a new reference passed to `r1_once`, with the original one preserved.

</details>

0 comments on commit 0dbb101

Please sign in to comment.