Custom reference types


#1

If I understand correctly, currently Rust has three shared reference types: &T, &[T], &str. Under the hood, &T is a pointer and &[T] and &str contain a pointer and a length. A function which expects a string should have an argument of type &str; &String is legal but isn’t efficient, since it adds another level of indirection to the string data.

I wondered if it may be possible to allow custom reference types. That is, for type T there would be a default type &T which is a pointer, but it will be possible to override the default so for example &String and &Vec would contain a pointer and a length. A method ref would have to be implemented, which creates a &T from a T (or, say, from a Ref<T> which would be a plain reference to T).

This would make the string and vector types less confusing, since there would be no types &[T] and &str, only &Vec and &String. (&str is especially confusing, since it suggests the existence of a type str). It would also remove the need to write s.as_slice() whenever you want to pass a String to a function - you would write &s just like with any other type.

It would also make other references more efficient: currently, in order to pass a HashMap to a function you have to use &HashMap, which contains an unneeded level of indirection. It would have been more efficient to pass the contents of the HashMap struct as long as the borrow checker makes sure that the data isn’t mutated. Custom reference types would make this possible.

Just like ~T was replaced with a type defined in the standard library, perhaps so could &str and &[T], while reducing complexity and removing unnecessary levels of indirection from other types.

Could this fit in Rust’s type system?

Noam


#2

This wouldn’t really fit into Rust’s type system all that well. Currently, an &T is a reference to a T. In your proposal, it would be a reference to something pointed to by a T. Doing it the way you suggest would prevent people from using double indirection deliberately so they can change where a pointer points. This breaks compositionality.

The direction Rust is currently going is to allow dynamically sized types, like str or [T]. You could then just reborrow (i.e. slice) a String to a &str the same way you would a Box<T> to an &T. Only dynamically sized types really need custom reference representations (like having a length), so there isn’t much point to giving programmers control over this.


#3

This is how I chose to understand your point:

Certain traits require Reference types to be passed or returned. For example Derefand DerefMut require that you return &T for some T. With DST vectors will be able to return &[T] from Deref, I think(!).

It would be useful for my own types – i.e Array – to return their own reference types for Deref – i.e. &ArrayView. Today, this isn’t possible.


#4

After further thinking of this, I revised the idea to make it well defined and quite feasible for implementation, I believe. I wrote about it in a new post: http://discuss.rust-lang.org/t/pass-references-by-value/318/18