Rust by example says ref is identical to a & but compiler doesn't agree on that

I am matching against the only element of a tuple struct.
when I do

match s.0 {
    Ok(d) => ...
}

or

match s.0 {
    Ok(&d) => ...
}

the code does not compile
but if I do

match s.0 {
    Ok(ref d) => ...
}

The code works just fine
And the rust by example says that ref and & are identical

https://doc.rust-lang.org/rust-by-example/scope/borrow/ref.html

It doesn't say that the equivalence holds universally, but qualifies it with:

As for your error, you haven't showed the exact code, but I suppose that you're matching on a reference to a tuple struct with a Result wrapping an owned non-Copy Ok variant, in which case the plain d in the match pattern would try to move out of a borrow (an error), &d would not match structurally (also an error), while ref d would successfully borrow the wrapped value.

So the entire idea of ref here is to express that im not matching a reference (therefore i cannot use &) but im getting the reference of the thing after the match. Is that correct ? @inejge

& in expression position and ref in pattern position are "duals" or "complements" in a sense. See my blog post on the topic.

2 Likes

Right. Apropos match, you should also pay attention to the cases where "match ergonomics"/"default binding modes" silently modifies match patterns, which can sometimes produce unintuitve results, cf #64586.

It is really helpful thanks