Esempio n. 1
0
// The subtype is a pointer, the supertype could be anything.
static bool is_pointer_subtype(ast_t* sub, ast_t* super)
{
  switch(ast_id(super))
  {
    case TK_NOMINAL:
    {
      // Must be a Pointer, and the type argument must be the same.
      return is_pointer(super) &&
        is_eq_typeargs(sub, super) &&
        is_sub_cap_and_ephemeral(sub, super);
    }

    case TK_TYPEPARAMREF:
    {
      // We must be a subtype of the constraint.
      ast_t* def = (ast_t*)ast_data(super);
      ast_t* constraint = ast_childidx(def, 1);

      return is_pointer_subtype(sub, constraint);
    }

    case TK_ARROW:
    {
      // We must be a subtype of the lower bounds.
      ast_t* lower = viewpoint_lower(super);
      bool ok = is_pointer_subtype(sub, lower);
      ast_free_unattached(lower);
      return ok;
    }

    default: {}
  }

  return false;
}
Esempio n. 2
0
// Both sub and super are nominal types.
static bool is_nominal_sub_nominal(ast_t* sub, ast_t* super)
{
  if(!is_sub_cap_and_ephemeral(sub, super))
    return false;

  ast_t* sub_def = (ast_t*)ast_data(sub);
  ast_t* super_def = (ast_t*)ast_data(super);

  // If we are the same nominal type, our typeargs must be the same.
  if(sub_def == super_def)
    return is_eq_typeargs(sub, super);

  switch(ast_id(super_def))
  {
    case TK_PRIMITIVE:
    case TK_CLASS:
    case TK_ACTOR:
      // If we aren't the same type, we can't be a subtype of a concrete type.
      return false;

    case TK_INTERFACE:
      // Check for an explicit provide or a structural subtype.
      return is_nominal_sub_trait(sub, super) ||
        is_nominal_sub_interface(sub, super);

    case TK_TRAIT:
      // Check for a nominal subtype.
      return is_nominal_sub_trait(sub, super);

    default: {}
  }

  return false;
}
Esempio n. 3
0
static bool is_trait_sub_trait(ast_t* sub, ast_t* super, errorframe_t* errors)
{
  // R = R' or implements(R, R')
  // k <: k'
  // ---
  // R k <: R' k'
  ast_t* sub_def = (ast_t*)ast_data(sub);
  ast_t* super_def = (ast_t*)ast_data(super);
  bool ret = true;

  if(sub_def == super_def)
  {
    if(!is_eq_typeargs(sub, super, errors))
      ret = false;
  }
  else if(!nominal_provides_trait(sub, super, errors))
  {
    ret = false;
  }

  if(!is_sub_cap_and_eph(sub, super, errors))
    ret = false;

  return ret;
}
Esempio n. 4
0
static bool is_nominal_sub_entity(ast_t* sub, ast_t* super,
  errorframe_t* errors)
{
  // N = C
  // k <: k'
  // ---
  // N k <: C k'
  ast_t* sub_def = (ast_t*)ast_data(sub);
  ast_t* super_def = (ast_t*)ast_data(super);
  bool ret = true;

  if(sub_def != super_def)
  {
    if(errors != NULL)
    {
      ast_error_frame(errors, sub, "%s is not a subtype of %s",
        ast_print_type(sub), ast_print_type(super));
    }

    return false;
  }

  if(!is_eq_typeargs(sub, super, errors))
    ret = false;

  if(!is_sub_cap_and_eph(sub, super, errors))
    ret = false;

  return ret;
}
Esempio n. 5
0
static bool exact_nominal(ast_t* a, ast_t* b)
{
  AST_GET_CHILDREN(a, a_pkg, a_id, a_typeargs, a_cap, a_eph);
  AST_GET_CHILDREN(b, b_pkg, b_id, b_typeargs, b_cap, b_eph);

  ast_t* a_def = (ast_t*)ast_data(a);
  ast_t* b_def = (ast_t*)ast_data(b);

  return
    (a_def == b_def) &&
    (ast_id(a_cap) == ast_id(b_cap)) &&
    (ast_id(a_eph) == ast_id(b_eph)) &&
    is_eq_typeargs(a, b, false);
}
Esempio n. 6
0
static bool is_nominal_eq_nominal(ast_t* sub, ast_t* super)
{
  ast_t* sub_cap = fetch_cap(sub);
  ast_t* sub_eph = ast_sibling(sub_cap);
  ast_t* super_cap = fetch_cap(super);
  ast_t* super_eph = ast_sibling(super_cap);

  token_id t_sub_cap = ast_id(sub_cap);
  token_id t_sub_eph = ast_id(sub_eph);
  token_id t_super_cap = ast_id(super_cap);
  token_id t_super_eph = ast_id(super_eph);

  if((t_sub_cap != t_super_cap) || (t_sub_eph != t_super_eph))
    return false;

  ast_t* sub_def = (ast_t*)ast_data(sub);
  ast_t* super_def = (ast_t*)ast_data(super);

  // If we are the same nominal type, our typeargs must be the same.
  if(sub_def == super_def)
    return is_eq_typeargs(sub, super);

  return false;
}