// 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; }
static bool is_nominal_sub_nominal(ast_t* sub, ast_t* super, errorframe_t* errors) { // N k <: N' k' ast_t* super_def = (ast_t*)ast_data(super); switch(ast_id(super_def)) { case TK_PRIMITIVE: case TK_STRUCT: case TK_CLASS: case TK_ACTOR: return is_nominal_sub_entity(sub, super, errors); case TK_INTERFACE: return is_nominal_sub_interface(sub, super, errors); case TK_TRAIT: return is_nominal_sub_trait(sub, super, errors); default: {} } assert(0); return false; }