Double reference is nothing special in Rust. In particular there’s no &&-token-having-special-meaning weirdness going on like in C++, instead a (prefix) && token has the same meaning as two seperate tokens & &.
For any type T, you can create the type of references to T, that is, &'a T. When T itself is the type of references to yet-another-type S, you can have &'a T being &'a &'b S. In case of S being i32, we’re back at your example. The implementation of something like &'c &'b i32 is with a pointer that points to yet another pointer whch in turn points to an i32-value.
You can dereference z: &'c &'b i32 back to a &'b i32 by writing *z. The underlying i32 then would be accessible under **z. Rust does have some priciples that can operate through multiple levels of indirection. For example, you can still call &self methods of a type S in a double reference &&S or even a triple reference &&&S, etc. Something like
let x: Option<i32> = Some(0);
// how about QUINTUPLE references?!?
let y: &&&&&Option<i32> = &&&&&x;
let z: bool = y.is_some();
works just fine. Rust also allows has implicit conversions (so-called “coercion”) that can remove extra layers of references, e.g.
let x: Option<i32> = Some(0);
let y: &&&&&Option<i32> = &&&&&x;
let z: &Option<i32> = y;
There’s also certain considerations on how exactly lifetimes work with multiple levels of shared (&) and/or mutable (&mut) references. E.g. sharing a mutable reference via &&mut T obviously doesn’t give you unique access to the underlying T anymore. And in a &'c &'b i32 reference, the inner lifetime 'b must always be longer than the outer lifetime 'c.
By the way, something like
let z: &'c &'b i32 = &'c y;
is not actually valid Rust code. You might see this as pseudo-code somewhere when people try to explain lifetimes, but you cannot introduce (or prescribe) the lifetime of a reference in the way that the expression &'c y seems to do.