Question

I'm using reference counters in the code (std::rc::Rc) to keep track of a record from multiple places within a data structure. However when i take the record out of the data structure I want to convert it to an owned pointer.

Ideally I would like to destroy all my reference counts and move the underlying record to an owned pointer (without having to copy it out of the Rc) but I don't think this is possible because there is no way to guarantee that I have destroyed all the Rc-s.

So instead I am trying to create the owned pointer by boxing up a clone. Here is a simplified example of what I'm trying to do:

use std::rc::Rc;

#[deriving(Show, Clone)]
struct Person {
  age: int,
  name: ~str,
}

fn main() {
  let x = Rc::new(Person{ age: 31, name: "Alex".to_owned() });
  let y = box (*x).clone();

  println!("{0:?}", *x);
  println!("{0:?}", y);
}

But when I compile this I get

work.rs:11:19: 11:20 error: unexpected token: `.`
work.rs:11   let y = box (*x).clone();
                         ^
alex@alex-xubuntu:~/src/sandbox$ rustc work.rs && ./work

Does anyone have any ideas why this doesn't work?

Note that the following does work, but at the cost of an additional copy:

use std::rc::Rc;

#[deriving(Show, Clone)]
struct Person {
  age: int,
  name: ~str,
}

fn main() {
  let x = Rc::new(Person{ age: 31, name: "Alex".to_owned() });
  let y = (*x).clone();
  let z = box y;

  println!("{0:?}", *x);
  println!("{0:?}", z);
}

Here's my rustc version:

alex@alex-xubuntu:~/src/sandbox$ rustc --version
rustc 0.11-pre (e454851 2014-05-08 06:11:37 -0700)
host: i686-unknown-linux-gnu

Thanks in advance.

Was it helpful?

Solution

The syntax of box allows placement; loose EBNF:

"box" [ "(" expr ? ")" ] expr

If the placement value is missing, it is taken to be ::std::owned::HEAP; for example, box foo is equivalent to box () foo and box (HEAP) foo.

This is tripping up your case, because it is interpreting *x as the placement value, and then it is trying to parse .clone() as an expression, which is not legal.

You must write it instead in a manner that takes this into consideration:

let y = box () (*x).clone();
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top