On 2/7/12 4:23 PM, Graydon Hoare wrote:
On 2/7/2012 3:24 PM, Niko Matsakis wrote:

Hm. I am confused at the description of the "hole" in the type system. I was under the impression that this was the distinction between immutable values and immutably-rooted values (those contained within a path-of-immutable-references). Am I misunderstanding?

I am talking about our type system as implemented. We treat immutable fields as covariantly typed, meaning that {x:T1} <: {x:T2} if T1 <: T2. This is sound so long as the field x is really immutable; but it is not. Here is an example of where this leads to bad results:

type T = { f: @const int };

fn foo(&t: T, v: @const int) {
    t = {f:v};
}

fn main() {
    let h = @3; // note: h is immutable
    let g = @mutable {f: @mutable 4};
    #error["h=%? g=%?", h, g]; // prints "h=@3 g=@(@4)"
    foo(*g, h); // after this point, g.f == h but with a new type
    #error["h=%? g=%?", h, g]; // prints "h=@3 g=@(@3)"
    *g.f = 5;
    #error["h=%? g=%?", h, g]; // prints "h=@5 g=@(@5)"
}

You can construct similar examples using vectors or fn types. If we were to make more use of subtyping, for example via refinement types such as those proposed in #1679, there would be many more such examples as well.


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

Reply via email to