Example #1
0
static bool is_typeparam_base_sub_x(ast_t* sub, ast_t* super,
  errorframe_t* errors)
{
  switch(ast_id(super))
  {
    case TK_UNIONTYPE:
      return is_x_sub_union(sub, super, errors);

    case TK_ISECTTYPE:
      return is_x_sub_isect(sub, super, errors);

    case TK_TUPLETYPE:
    case TK_NOMINAL:
      return false;

    case TK_TYPEPARAMREF:
      return is_typeparam_sub_typeparam(sub, super, errors);

    case TK_ARROW:
      return is_typeparam_sub_arrow(sub, super, errors);

    default: {}
  }

  assert(0);
  return false;
}
Example #2
0
// The subtype is a typeparam, the supertype could be anything.
static bool is_typeparam_subtype(ast_t* sub, ast_t* super)
{
  switch(ast_id(super))
  {
    case TK_TYPEPARAMREF:
      if(is_typeparam_sub_typeparam(sub, super))
        return true;
      break;

    case TK_UNIONTYPE:
      if(is_subtype_union(sub, super))
        return true;
      break;

    case TK_ISECTTYPE:
      if(is_subtype_isect(sub, super))
        return true;
      break;

    case TK_ARROW:
      if(is_subtype_arrow(sub, super))
        return true;
      break;

    default: {}
  }

  // We can be a subtype if our upper bounds, ie our constraint, is a subtype.
  ast_t* sub_def = (ast_t*)ast_data(sub);
  ast_t* constraint = ast_childidx(sub_def, 1);

  if(ast_id(constraint) == TK_TYPEPARAMREF)
  {
    ast_t* constraint_def = (ast_t*)ast_data(constraint);

    if(constraint_def == sub_def)
      return false;
  }

  // Constraint must be modified with sub ephemerality.
  AST_GET_CHILDREN(sub, name, cap, eph);
  ast_t* r_constraint = set_cap_and_ephemeral(constraint, TK_NONE,
    ast_id(eph));

  bool ok = is_subtype(r_constraint, super);
  ast_free_unattached(r_constraint);

  return ok;
}