mozilla/rust — pull request #9841 by dwrensha (2013-10-14 00:27:00+00:00)
Title: Issue 7331

Closes #7331.

Motivating example:
```
trait FromVec<'self> {
fn fromVec(&'self [u8]) -> Self;
}

struct Reader<'self> {
v : &'self [u8]
}

impl <'self> FromVec<'self> for Reader<'self> {
fn fromVec(v : &'self [u8]) -> Reader<'self> {
Reader::<'self> { v : v }
}
}

impl <'self, T : FromVec<'self>> Reader<'self> {
fn get(self) -> T {
FromVec::fromVec(self.v);
}
}
```

When we typecheck `FromVec::fromVec`, we get `fn(&'self [u8]) -> T` where `T` is bounded by `FromVec<'self>`. Usually we would replace the argument's `'self` with a new region variable which could match anything. However, if we allow that here then we lose an important constraint between the argument and the return type `T`, namely that the `'self` in `FromVec<'self>` needs to be the same as the argument's `'self`.

In this patch, I handle this case by replacing the argument's `'self` with the free region that has already been constructed for `'self` in the enclosing scope.

Note that I remove the region param from static trait methods (line 360 of collect.rs). The main motivation for that change is to provide a more sensible error message on something like `FromVec::fromVec::<'self>(self.v)`, which would otherwise confusingly yield the error message "this trait has a lifetime parameter but no lifetime was specified". Moreover, although it could be argued that these methods technically still are region-parameterized, the actual plugged-in region is always the same thing---a free region associated with `'self`; I think it's prudent to syntactically prevent anyone from trying to plug anything else in.