WIP: Incorporate variance into typeck

Currently, rustc only does so for regions substitution. Applies the same
rule to type and self parameter substitution.

With all three substitutions on, the following becomes legitimate:

```rust
fn foo<'a, 'b>(x: &'b Option<&'a int>) -> Option<&'b int> {
    *x
}
```

`x` here is contravariant with respect to the region parameter `b`, so
it is eligible to the return position, also contravariant.

It is also found that rustc handled one special case incorrectly. In
variance inference pass, constraints are added and then solved. But rustc
didn't add any constraint for nullary generic enum and struct so they
were classified as bivariant, the default. Then the following two
implementations of `Foo`:

```rust
pub struct S<T>;

impl Foo for S<int> {
    fn bar(&self) {}
}

impl Foo for S<uint> {
    fn bar(&self) {}
}
```

would be identical therefor conflicting under type substitution, which
is incorrect.

Closes #3598.
Closes #5781.