mozilla/rust — pull request #4070 by brson (2012-11-29 19:35:35+00:00)
Title: Trait inheritance for bounded type parameters

This makes trait inheritance work for lots of test cases involving bounded type parameters, type substitutions and static methods.

Here's one with type substitutions: https://github.com/brson/rust/blob/39dbf4fe74925b1c238c8bc82911e85fd91c3d0b/src/test/run-pass/trait-inheritance-overloading.rs

And one with static methods: https://github.com/brson/rust/blob/39dbf4fe74925b1c238c8bc82911e85fd91c3d0b/src/test/run-pass/trait-inheritance-static2.rs

The basic strategy it uses is to expand bound lists to include their supertraits, in

```
trait A { } trait B: A { }
fn() { }
```

`` is treated in the internal vtable calculations as ``. This is made easier and more obvious by the limitation that each impl implements a single trait, not that trait and its supertraits.

```
trait A { fn f() }
trait B: A { fn g() }

impl S: A { fn f() }
impl S: B { fn g() }
```

This limitation makes the implementation straightforword and has no new implications for coherence. `trait B: A` just means that to instantiate B there must also be an impl of A. The trait inheritance list has strong parallels to the bounded typaram list.

I still don't understand type substitutions and why [`lookup_vtables`](https://github.com/brson/rust/blob/39dbf4fe74925b1c238c8bc82911e85fd91c3d0b/src/librustc/middle/typeck/check/vtable.rs#L52) and [`push_inherent_candidates_for_param`](https://github.com/brson/rust/blob/39dbf4fe74925b1c238c8bc82911e85fd91c3d0b/src/librustc/middle/typeck/check/method.rs#L308) do their substitutions differently. You can see that `push_inherent_candidates_for_param` is the only code that does the trait hierarchy traversal that doesn't use the new `iter_bound_traits_and_supertraits` code because it needs to thread substitutions through. I could keep going and try to abstract `iter_bound_traits_and_supertraits` into a generic fold but I figure now is the time to get review and see if this is looking ok.

Future work:
* Ensure that all supertraits have impls when implementing a trait. i.e. if I define `impl S: B { }` there should also be an `impl S: A { }` somewhere. This isn't required for soundness since the lack of A will be detected when somebody tries to actually use `S` as `A`, but it makes sense to enforce.
* Objects and inheritance. They don't work yet.
* Failure test cases