[rust-dev] paring back the self type to be, well, just a type

Niko Matsakis nmatsakis at mozilla.com
Thu Apr 12 09:18:01 PDT 2012


I've been reading more closely into the impl/iface code and I think I've 
found another problem. The current `self` type is actually more than a 
type---rather it's a kind of type constructor.  I think we should change 
it to be just a type, because we do not have other type constructors in 
our system and in general things do not hold together.  Let me explain 
briefly what I mean.

Currently, the type `self` refers to "the type implemented the current 
iface".  However, the self type is parameterized just as the containing 
iface.  So, technically, you could have an iface like:

     iface foo<T> {
         fn bar<S>(x: self<S>);
     }

Now this would correspond to an impl like:

     impl of foo<T> for [T] {
         fn bar<S>(x: [S]) { ... }
     }

Here, the type `self<S>` was transformed to `[S]`.  This is a fairly 
complex transformation, actually, as must "reverse-link" the parameter T 
from its use in `[T]` to the appearance in `foo<T>` and so forth.  In 
fact, this transformation is not especially well-defined: there may be 
multiple types or no types which are equally valid.

To see why there could be multiple types, consider something like 
`impl<X> of foo<T> for either<T,X>`.  What type does `self<S>` have?  It 
would be valid for any `either<S,?>`.

To see why there might be no types, consider something like `impl of 
foo<uint> for uint`.  What type does `self<S>` have?  Or, similarly, 
consider:

     fn some_func<T: foo<uint>>(t: T) {
         t.bar(...);
     }

What is the type of the parameter expected by `bar`?

In other languages, there is support for parameterizing a function or 
type by a "type constructor" (which is essentially what `self` is).  I 
don't think we need those capabilities, though of course we could add 
them later.

I would rather see the `self` type be like any other type parameter: 
non-parameterized.   In that case, the iface shown above would be 
invalid. This does naturally mean that our type system is less 
expressive.  However, its behavior is well-defined in all cases, which 
seems like a nice property to have.


Niko


More information about the Rust-dev mailing list