// The subtype is an isect, the supertype could be anything. static bool is_isect_subtype(ast_t* sub, ast_t* super) { if(ast_id(super) == TK_ISECTTYPE) return is_isect_sub_isect(sub, super); // One element of the intersection must be a subtype of super. ast_t* child = ast_child(sub); while(child != NULL) { if(is_subtype(child, super)) return true; child = ast_sibling(child); } return false; }
static bool is_isect_sub_x(ast_t* sub, ast_t* super, errorframe_t* errors) { switch(ast_id(super)) { case TK_ISECTTYPE: // (T1 & T2) <: (T3 & T4) return is_isect_sub_isect(sub, super, errors); case TK_NOMINAL: { ast_t* super_def = (ast_t*)ast_data(super); // TODO: can satisfy the interface in aggregate // (T1 & T2) <: I k if(ast_id(super_def) == TK_INTERFACE) { // return is_isect_sub_interface(sub, super, errors); } break; } default: {} } // T1 <: T3 or T2 <: T3 // --- // (T1 & T2) <: T3 for(ast_t* child = ast_child(sub); child != NULL; child = ast_sibling(child)) { if(is_subtype(child, super, NULL)) return true; } if(errors != NULL) { ast_error_frame(errors, sub, "no element of %s is a subtype of %s", ast_print_type(sub), ast_print_type(super)); } return false; }