compiler: RecordLikeType cleanups

- Move RecordLikeType out of the Scheme type hierarchy. RecordLikeType
  and ClosureType don't represent actual types and are instead used to
  share code with record types. Instead we can make RecordLikeType a
  trait and have RecordType extend both RecordLikeType and Scheme Type.

  This removes some special cases elsewhere in the compiler that throw
  InternalCompilerErrorException when they encounter a closure type.

- In PackedRecordLike we don't need to recalculate the size of the
  packed struct as we're using perfect ordering. Instead just sum the
  size of all the packed fields

- Have ParseRecordTypeDefine.parseConstructor build its own nameToField
  map from the recordType argument instead of having it passed in
  explicitly.
compiler: Support for recursive record types

- Hide the type of a record field under RecordField.typeTemplate and
  make all callers go through RecordLikeType.typeForField to access it.
  This allows us to expand the recursive type variable without
  introducing mutable data to record type system. This also lays
  groundwork for polymorphic record types

- In ParseRecordTypeDefine introduce a polymorphic type variable
  referencing the record type being defined

- Store the recursive type variable in RecordType.selfTypeVarOpt and
  have RecordType.typeForField instantiate the field type with the
  record type bound to its self type variable

Closes #29