Function return a vector of shared ghost cell

Hi All,

I am trying to make the following code work:

use ghostcell::GhostToken;
use ghostcell::GhostCell;
use std::vec::Vec;

pub fn counter<'id>(
    token : &mut GhostToken<'id>,
    n : i64
) -> Vec<&GhostCell<'id, i64>> {
    let c = GhostCell:: new (n);

    let vec: Vec<_> = (0..1).map(|_|&c).collect();
    vec
   
}

fn main() {
   
    GhostToken::new(|mut token| {
       
        let vec = counter(&mut token, 0);
       
        let a: &i64 = vec[0].borrow_mut(&mut token);
        *a = *a + 1;
        println!("{}", a);
        let b: &i64 = vec[1].borrow_mut(&mut token);
        *b = *b + 1;
        println!("{}", b);
    });
}

Based on my understanding, shared ghost cells need to be put into a container and uses the token to access it. But a function returning a vector needs lifetime parameters. See the error below:

  token : &mut GhostToken<'id>,
  |             --------------------
7 |     n : i64
8 | ) -> Vec<&GhostCell<'id, i64>> {
  |          ^ expected named lifetime parameter


Adding a lifetime parameter:

pub fn counter<'a, 'id>(
    token : &mut GhostToken<'id>,
    n : i64
) -> Vec<& 'a GhostCell<'id, i64>> {
    let c = GhostCell:: new (n);

    let vec: Vec<_> = (0..1).map(|_|&c).collect();
    vec
   
}

It will complain:

  let vec: Vec<_> = (0..1).map(|_|&c).collect();
   |                                  ^^^ - `c` is borrowed here
   |                                  |
   |                                  may outlive borrowed value `c`

Is there a way to make it work?

Please read the pinned post on code formatting and fix the code in your post.

2 Likes

Sorry..., fixed.

3 Likes

I don't know much about the intended use of GhostCells, but Rust's normal borrowing rules apply to them, so this isn't going to work with any amount of lifetime parameters, for the same reason it won't work with any other type: you can't return a reference to a local variable. Note also that token is unused in that function, so the particular semantics of GhostCells is not being directly interacted with. Inlining the counter() function is probably the easiest way to get this working (the borrow_mut() should also return a &mut i64), although I haven't tested it:

fn main() {
   
    GhostToken::new(|mut token| {
        let c = GhostCell:: new (n);

        let vec: Vec<_> = (0..1).map(|_|&c).collect();
       
        let a: &mut i64 = vec[0].borrow_mut(&mut token);
        *a = *a + 1;
        println!("{}", a);
        let b: &mut i64 = vec[1].borrow_mut(&mut token);
        *b = *b + 1;
        println!("{}", b);
    });
}

However, it isn't clear why you want the references to the GhostCell to be in a vector here, other than to demonstrate that the two references coexist and don't prevent the mutable borrow. GhostCells seems most useful when references to them are distributed to different threads, and the GhostToken is then passed to indicate which thread has access permissions.

1 Like

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.