When writing an email stating “your programming language isn’t expressive 
enough”, it’s a good idea to include an example program that you would like to 
write that is rejected by the current type system. Then people replying to your 
email can give you some suggestions on how to best achieve your goals in Rust. 
The usual solution to the problem of safely mutating data is to use Cell, but 
we can’t be sure unless you give an example.

You are correct that mutation is only a risk to memory safety after 
deallocation occurs, but in a language with actual sum types this can occur 
when mutating a variable of a sum type to hold a different variant, since the 
storage is reused for a new variant after mutation, invalidating any references 
into the previous data. However, this doesn’t require preventing the mutation 
of things like integer fields of a struct.

The current guarantee (or the projected guarantee, since this isn’t actually 
implemented in all cases) for &mut references is that all accesses (both reads 
and writes) to &mut data occur through access paths derived from the &mut 
reference. This is helpful because the same guarantee holds regardless of type, 
and the guarantee is strong enough to provide race-free accesses to shared data.

Rust used to have an &const pointer type, which was similar to C++’s const in 
that it guaranteed that modifications didn’t occur through access paths derived 
from the &const pointer, but still allowed them to occur through other access 
paths. From what I understand, it was removed to simplify the type system, 
since most of its uses could be replaced with Cell.

In full generality, you could imagine Rust pointers allowing the specification 
of the following information:

1) Specific derived access paths that are unique, similar to the guarantee 
provided by &mut or the internal &uniq today.

2) Specific derived access paths that may be read through this pointer.

3) Specific derived access paths that may be mutated through this pointer.

4) Specific derived access paths that may observe mutations through access 
paths that do not involve this pointer.

Obviously, not all combinations would be sound or even coherent. This system 
would still permit reborrowing and would allow some interesting situations that 
are forbidden today. For example, you could have a vector v of

struct A { a: int, b: Box<int> }

and have an unrestricted number of mutable/const borrows of the path v[].a but 
a unique mutable borrow of v[].b and all derived paths. You could also pass 
partially initialized structs to other functions, knowing that they don’t read 
any of the uninitialized fields.

Would this be a better type system? Well, it would definitely be more 
expressive than the current system, and it wouldn’t even be extremely difficult 
to modify the borrow checker to implement it. However, it would be a dramatic 
increase in user-facing complexity, since shorthand would only take you so far. 
These complex pointer types would have to appear in every function signature. 
They would also leak implementation details of functions and types even moreso 
than Rust already does.

Cameron

On May 31, 2014, at 10:36 AM, Tommi <rusty.ga...@icloud.com> wrote:

> It certainly feels like a failure of the Rust type system that you cannot 
> have multiple mutating references to the same variable when the variable is 
> accessed only from a single thread. I know the reason for this is to prevent 
> iterator invalidation, but this is too blunt of an instrument.
> 
> Iterator invalidation (as it's known in C++) is a risk to memory safety only 
> when some of the memory that is accessible through an iterator (or a 
> reference) is deallocated. A better type system would make a distinction 
> between those expressions that may deallocate and those that cannot. Then, 
> when multiple mutating references pointed to the same variable, the compiler 
> would disallow only the use of the potentially deallocating expressions 
> through those references.
> 
> If a variable may be accessed concurrently from multiple threads, only then 
> would the current "no mutating references allowed to that variable" -rule be 
> enforced.
> 
> Sorry for the brevity, I'm writing this from a phone and I haven't thought of 
> this issue very thoroughly.
> 
> _______________________________________________
> Rust-dev mailing list
> Rust-dev@mozilla.org
> https://mail.mozilla.org/listinfo/rust-dev

_______________________________________________
Rust-dev mailing list
Rust-dev@mozilla.org
https://mail.mozilla.org/listinfo/rust-dev

Reply via email to