Change substitutions from a flat vector into 3 vectors

The current setup is to have a single vector of type parameters in
scope at any one time. We then have to concatenate the parameters from
the impl/trait with those of the method. This makes a lot of things
awkward, most notably associated fns ("static fns"). This branch
restructures the substitutions into three distinct namespaces (type,
self, fn). This makes most of the "type parameter management"
trivial. This also sets us up to support UFCS (though I haven't made
any particular changes in that direction in this patch).

Along the way, this patch fixes a few miscellaneous bits of code cleanup:

1. Patch resolve to detect references to out-of-scope type parameters,
   rather than checking for "out of bound" indices during substitution
   (fixes #14603).

2. Move def out of libsyntax into librustc where it belongs. I should have
   moved DefId too, but didn't.
   
3. Permit homogeneous tuples like `(T, T, T)` to be used as fixed-length
   vectors like `[T, ..3]`. This is awfully handy, though public facing.
   I suppose it requires an RFC.

4. Add some missing tests.

cc #5527

r? @pcwalton or @pnkfelix