Why does Rust implement async by Pin instead of relative pointer?

Why does Rust implement async by Pin instead of the relative pointer? Rust uses Pin to implement self-referential structure. Are there any technical reason for that?

You can take a reference to a local variable and pass it or store it anywhere as long as it doesn't outlive the frame. This includes locations that also simultaneously have to support normal references.

For example: Rust Playground

use std::collections::HashMap;
use std::future::Future;

static S: i32 = 5;

async fn f(p: &i32, f: impl Future) -> i32 {
    let x = 3;
    let mut map = HashMap::new();
    map.insert(1, &x);
    map.insert(2, p);
    map.insert(3, &S);
    
    f.await;
    
    *map.get(&1).unwrap() + *map.get(&2).unwrap() + *map.get(&3).unwrap()
}

The type of map is just HashMap<i32, &i32>- there's no way for it to store both "normal" &i32s for p and S and a special "relative" pointer for x. What would it even be relative to at this point?

7 Likes