Example #1
0
bool is_known(ast_t* type)
{
  if(type == NULL)
    return false;

  switch(ast_id(type))
  {
    case TK_UNIONTYPE:
    case TK_TUPLETYPE:
      return false;

    case TK_ISECTTYPE:
    {
      ast_t* child = ast_child(type);

      while(child != NULL)
      {
        if(is_known(child))
          return true;

        child = ast_sibling(child);
      }

      return false;
    }

    case TK_NOMINAL:
    {
      ast_t* def = (ast_t*)ast_data(type);

      switch(ast_id(def))
      {
        case TK_INTERFACE:
        case TK_TRAIT:
          return false;

        case TK_PRIMITIVE:
        case TK_STRUCT:
        case TK_CLASS:
        case TK_ACTOR:
          return true;

        default: {}
      }
      break;
    }

    case TK_ARROW:
      return is_known(ast_childidx(type, 1));

    case TK_TYPEPARAMREF:
      return is_known(typeparam_constraint(type));

    default: {}
  }

  assert(0);
  return false;
}
Example #2
0
bool is_entity(ast_t* type, token_id entity)
{
  if(type == NULL)
    return false;

  switch(ast_id(type))
  {
    case TK_TUPLETYPE:
      return false;

    case TK_UNIONTYPE:
    {
      ast_t* child = ast_child(type);

      while(child != NULL)
      {
        if(!is_entity(child, entity))
          return false;

        child = ast_sibling(child);
      }

      return true;
    }

    case TK_ISECTTYPE:
    {
      ast_t* child = ast_child(type);

      while(child != NULL)
      {
        if(is_entity(child, entity))
          return true;

        child = ast_sibling(child);
      }

      return false;
    }

    case TK_NOMINAL:
    {
      ast_t* def = (ast_t*)ast_data(type);
      return ast_id(def) == entity;
    }

    case TK_ARROW:
      return is_entity(ast_childidx(type, 1), entity);

    case TK_TYPEPARAMREF:
      return is_entity(typeparam_constraint(type), entity);

    default: {}
  }

  assert(0);
  return false;
}
Example #3
0
ast_result_t flatten_typeparamref(pass_opt_t* opt, ast_t* ast)
{
  ast_t* cap_ast = cap_fetch(ast);
  token_id cap = ast_id(cap_ast);

  typeparam_set_cap(ast);

  token_id set_cap = ast_id(cap_ast);

  if((cap != TK_NONE) && (cap != set_cap))
  {
    ast_t* def = (ast_t*)ast_data(ast);
    ast_t* constraint = typeparam_constraint(ast);

    if(constraint != NULL)
    {
      ast_error(opt->check.errors, cap_ast, "can't specify a capability on a "
        "type parameter that differs from the constraint");
      ast_error_continue(opt->check.errors, constraint,
        "constraint definition is here");

      if(ast_parent(constraint) != def)
      {
        ast_error_continue(opt->check.errors, def,
          "type parameter definition is here");
      }
    } else {
      ast_error(opt->check.errors, cap_ast, "a type parameter with no "
        "constraint can only have #any as its capability");
      ast_error_continue(opt->check.errors, def,
        "type parameter definition is here");
    }

    return AST_ERROR;
  }

  return AST_OK;
}