If we make the changes I suggested in issue 2941, I think we can implement a freezable/sendable hashtable.
Here is the basic idea. You define a closed hashtable like so:
type hash<T> = {hashf: ~fn(T) -> uint, eqf: ~fn(T, T) -> bool, data: ~[T]};
Then you can define methods in two groups, those that mutate and those that do not. Mutating methods might look like this:
impl methods<T> for &mut hash<T> { ... }
Here, a borrowed mutable reference is used, which means that the various fields will be mutable, including data, and (according to this unique rule) including the contents of the data array as well.
Non-mutating methods look like one of the two following things:
impl methods<T> for &const hash<T> { ... }
impl methods<T> for &hash<T> { ... }
The latter is preferable, it specifies that the hashtable is immutable. This would be good methods that iterate over the hashtable or need to create lasting aliases. The const methods might be suitable for cases that do not involve borrowing pointers (basically not iteration). It's sort of a drag that we have to think about const vs immutable but it seems to be necessary for maximum flexibility.
These hashtables can be sent between tasks; they can be placed in ARCs; they can be "frozen" and shared within a task just by moving them into a shared box (@hash
).