示例#1
0
文件: flatten.c 项目: aturley/ponyc
static ast_result_t flatten_isect(pass_opt_t* opt, ast_t* ast)
{
  // Flatten intersections without testing subtyping. This is to preserve any
  // type guarantees that an element in the intersection might make.
  // If there are more than 2 children, this has already been flattened.
  if(ast_childcount(ast) > 2)
    return AST_OK;

  AST_EXTRACT_CHILDREN(ast, left, right);

  if((opt->check.frame->constraint == NULL) &&
    (opt->check.frame->iftype_constraint == NULL) &&
    (opt->check.frame->provides == NULL) &&
    !is_compat_type(left, right))
  {
    ast_add(ast, right);
    ast_add(ast, left);

    ast_error(opt->check.errors, ast,
      "intersection types cannot include reference capabilities that are not "
      "locally compatible");
    return AST_ERROR;
  }

  flatten_typeexpr_element(ast, left, TK_ISECTTYPE);
  flatten_typeexpr_element(ast, right, TK_ISECTTYPE);

  return AST_OK;
}
示例#2
0
static bool is_arrow_compat_arrow(ast_t* a, ast_t* b)
{
  // S = this | A {#read, #send, #share, #any}
  // K = N k | A {iso, trn, ref, val, box, tag} | K->K | (empty)
  // L = S | K
  // T = N k | A k | L->T
  //
  // forall K' in S . K->S->T1 {S |-> K'} ~ T2 {S |-> K'}
  // ---
  // K->S->T1 ~ T2
  ast_t* r_a;
  ast_t* r_b;

  if(viewpoint_reifypair(a, b, &r_a, &r_b))
  {
    bool ok = is_compat_type(r_a, r_b);
    ast_free_unattached(r_a);
    ast_free_unattached(r_b);
    return ok;
  }

  // No elements need reification.
  //
  // lowerbound(T1->T2) ~ lowerbound(T3->T4)
  // ---
  // T1->T2 ~ T3->T4
  r_a = viewpoint_lower(a);

  if(r_a == NULL)
    return false;

  r_b = viewpoint_lower(b);

  if(r_b == NULL)
  {
    ast_free_unattached(r_a);
    return false;
  }

  bool ok = is_compat_type(r_a, r_b);
  ast_free_unattached(r_a);
  ast_free_unattached(r_b);
  return ok;
}
示例#3
0
static bool is_arrow_compat_nominal(ast_t* a, ast_t* b)
{
  // lowerbound(T1->T2) ~ N k
  // ---
  // T1->T2 ~ N k
  ast_t* a_lower = viewpoint_lower(a);

  if(a == NULL)
    return false;

  bool ok = is_compat_type(a_lower, b);
  ast_free_unattached(a_lower);
  return ok;
}
示例#4
0
static bool is_union_compat_x(ast_t* a, ast_t* b)
{
  // T1 ~ T3 or T2 ~ T3
  // ---
  // (T1 | T2) ~ T3
  for(ast_t* child = ast_child(a);
    child != NULL;
    child = ast_sibling(child))
  {
    if(is_compat_type(child, b))
      return true;
  }

  return false;
}
示例#5
0
static bool is_tuple_compat_tuple(ast_t* a, ast_t* b)
{
  // T1 ~ T3
  // T2 ~ T4
  // ---
  // (T1, T2) ~ (T3, T4)
  ast_t* a_child = ast_child(a);
  ast_t* b_child = ast_child(b);

  while((a_child != NULL) && (b_child != NULL))
  {
    if(!is_compat_type(a_child, b_child))
      return false;

    a_child = ast_sibling(a_child);
    b_child = ast_sibling(b_child);
  }

  return (a_child == NULL) && (b_child == NULL);
}
示例#6
0
static bool is_arrow_compat_typeparam(ast_t* a, ast_t* b)
{
  // forall k' in k . T1->T2 {A k |-> A k'} ~ A k'
  // ---
  // T1->T2 ~ A k
  ast_t* r_a = viewpoint_reifytypeparam(a, b);
  ast_t* r_b = viewpoint_reifytypeparam(b, b);

  if(r_a != NULL)
  {
    bool ok = is_compat_type(r_a, r_b);
    ast_free_unattached(r_a);
    ast_free_unattached(r_b);
    return ok;
  }

  // lowerbound(T1->T2) ~ A k
  // ---
  // T1->T2 ~ A k
  return is_arrow_compat_nominal(a, b);
}