Working semantic checking for lists

It looks like generic lists will be less straightforward than I thought, so getting semantic checking in now to ward off merge conflicts.

Semantic list checking correctly recursively checks the type hierarchy to make sure inner elements match.
Well, it actually just generates incorrect code that doesn't compile- this was from before we had named types for each kind of list.