code: func (rt returnType) tysubst(typ reflect.Type) reflect.Type {
  	if tyname := tyvarName(typ); len(tyname) > 0 {
  		if thetype, ok := rt.tyenv[tyname]; !ok {
  			rt.panic("Unbound type variable %s.", tyname)
  		} else {
  			return thetype
  		}
  	}
  
  	switch typ.Kind() {
  	case reflect.Array:
  		rt.panic("Cannot dynamically create Array types.")
  	case reflect.Chan:
  		return reflect.ChanOf(typ.ChanDir(), rt.tysubst(typ.Elem()))
  	case reflect.Func:
  		rt.panic("Cannot dynamically create Function types.")
  	case reflect.Interface:
  		// rt.panic("TODO")
  		// Not sure if this is right.
  		return typ
  	case reflect.Map:
  		return reflect.MapOf(rt.tysubst(typ.Key()), rt.tysubst(typ.Elem()))
  	case reflect.Ptr:
  		return reflect.PtrTo(rt.tysubst(typ.Elem()))
  	case reflect.Slice:
  		return reflect.SliceOf(rt.tysubst(typ.Elem()))
  	case reflect.Struct:
  		rt.panic("Cannot dynamically create Struct types.")
  	case reflect.UnsafePointer:
  		rt.panic("Cannot dynamically create unsafe.Pointer types.")
  	}
  
  	// We've covered all the composite types, so we're only left with
  	// base types.
  	return typ
  }
docs: // tysubst attempts to substitute all type variables within a single return
  // type with their corresponding Go type from the type environment.
  //
  // tysubst will panic if a type variable is unbound, or if it encounters a
  // type that cannot be dynamically created. Such types include arrays,
  // functions and structs. (A limitation of the `reflect` package.)