Thanks for the answers; mostly it all makes sense, but I have a few follow-up questions.
Also note that vec[int] has gone away from the compiler; we've been changing from always-shared-and-refcounted vectors to more explicitly differentiated vectors: those with uniquely-owned components and/or possibly-shared components. Vectors are somewhat of a special case though. For the rest of this email, let's try talking about non-vectors -- say, integers, tuples, records, etc. -- as it makes the topic a bit clearer :)
I don't quite follow the distinctions here. How do I notate a vector with uniquely-owned components? "vec[~T]" vs "vec[@T]"? Also, what is the distinction between a "vec" and an "ivec"?
* A box type like @T is an instance of type T that lives in the heap.
The value in the box is immutable. To make it mutable, you do @mutable T.
Correct. More specifically @T is a *shared* boxed T. It has a refcount and/or a word of GC header, such that multiple @T variables can point to the same shared heap allocation.

We are also in the process of implementing a *unique* box type ~T where there is always exactly one ~T variable pointing to the heap allocation.
What will be the syntax for working with this unique box type?
* Equality is "deep" equality for values of type "T", "&T", "*T",
pointer equality for mutable values like "@mutable T" or records with
mutable fields.
Not quite. I think at present we're doing (or aiming to do) this:

   T :  interior values, compare contents
  ~T :  unique pointers, compare contents
  @T :  shared pointers, compare pointer-value
  *T :  unsafe pointers, compare pointer-value
&T :  alias values, compare however aliased type compares
This more-or-less corresponds to what I expected. However, it's not quite what I observed. For example:

    if @[1,2,3] == (@[1,2] + @[3]) {
        stdout.write_line("TRUE");
    }

prints "TRUE". I guess the pointers could be equal but it would be a bit surprising to me.
This would explain why a variable "x" of type "@T" cannot be used as the
value for a parameter of type "&T", and one must write "*x" instead,
because "*x" makes a temporary copy of the value at the time of the call.
It doesn't make a temporary copy. It just dereferences the shared @ pointer, so the alias points to the interior of the box. Otherwise the alias would point to the @ itself.

For example, all this code is correct (if slightly odd):

fn takes_a_box_alias(x: &@int) { log *x; }

fn takes_an_int_alias(x: &int) { log x; }

fn main() {
    let y = @10;
    takes_a_box_alias(y);
    takes_an_int_alias(*y);
}
So this clearly gets into the alias analysis discussion that I saw earlier (and didn't fully follow, as I hadn't experimented much with Rust yet). In other words, changes to a mutable alias argument, may affect the other alias parameters, possibly freeing interior values and so forth. Is there a summary of the current alias rules (intended or implemented, as the case may be)?


Niko


_______________________________________________
Rust-dev mailing list
[email protected]
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to