# Somewhat Random Idea: Deref patterns

**URL:** <https://internals.rust-lang.org/t/somewhat-random-idea-deref-patterns/13813>\
**Category:** Uncategorized\
**Created:** [January 12, 2021, 2:36am UTC](https://internals.rust-lang.org/t/somewhat-random-idea-deref-patterns/13813 "2021-01-12T02:36:31Z")\
**Posts on this page:** 1\
**Showing post:** 14

<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:** [January 12, 2021, 6:13pm UTC](https://internals.rust-lang.org/t/somewhat-random-idea-deref-patterns/13813/14 "2021-01-12T18:13:07Z")

</div>

> [@steffahn](#):
>
> I’m not sure whether e.g. casting (transmuting) a `&&T` to `&&mut T` is a safe thing to do, if it is then this last problem with the guards be easily solved, because then you’d just need to replace every `n` with `*m` where `m: &&mut T` is the result of such a cast.

Hm.. might not be enough yet, since, apparently, you _can_ tell that the immutable reference you get to see in the guard is _really_ the same one as you get in the body of the match arm. This is possible through them having the same lifetime; it’s e.g possible to keep immutable re-borrows from the guard around and get effects such as in the following example:

```rust
#![feature(box_patterns)]
fn foo() {
    let (mut x, y) = ((1,), 2);
    let mut x_r = Box::new(x);
    let mut y_r = &y;
    let _v = *y_r;
    match x_r {
        box (ref mut r,)
            if {
                y_r = &*r;
                true
            } => {
                let _v = *y_r;
                *r = 1;
                // not okay here
                // let _v = *y_r;
            }
        _ => {}
    }
}

```

This cannot be compiled in the fashion I suggested above.

On the other hand, what sane code needs to _rely_ on the fact that a by-reference capture has a particularly long lifetime _in a guard_? What I’m saying is: I wouldn’t be sad if the above code stopped compiling for a deref-based pattern-matching feature (instead of the `box` pattern).

* * *

_Edit:_ fun fact, I didn’t even know it was possible that multiple subsequent patterns in a guard can create conflicts in the borrow checker, but here we go

```rust
let mut x = Some(42);
let mut z = &0;
match &mut x {
    Some(ref y) if {
        z = y;
        false
    } => {}
    Some(ref mut _y) => {
        println!("{}", *z);
    }
    _ => {}
}

```

```rust
error[E0502]: cannot borrow value as mutable because it is also borrowed as immutable
  --> src/main.rs:9:10
   |
5 | Some(ref y) if {
   | ----- immutable borrow occurs here
...
9 | Some(ref mut _y) => {
   | ^^^^^^^^^^ mutable borrow occurs here
10 | println!("{}", *z);
   | -- immutable borrow later used here

```

Also noteworthy is how this code

```rust
let mut x = Some(42);
let mut z = &0;
match &mut x {
    Some(ref y) if {
        z = y;
        false
    } => {}
    Some(ref _y) => {
        println!("{}", *z);
    }
    _ => {}
}

```

prints `42`, yet still complains (incorrectly, I guess) about

```rust
   Compiling playground v0.0.1 (/playground)
warning: value assigned to `z` is never read
 --> src/main.rs:6:9
  |
6 | z = y;
  | ^
  |
  = note: `#[warn(unused_assignments)]` on by default
  = help: maybe it is overwritten before being read?

```

---

_[View the full topic](https://internals.rust-lang.org/t/somewhat-random-idea-deref-patterns/13813)._
