Skip to content

Commit

Permalink
Implement RFC 54 (subtyping exclusion) (ponylang#2678)
Browse files Browse the repository at this point in the history
Added `nosupertype` annotation for subtyping exclusion (RFC 54).
  • Loading branch information
Benoit Vey authored and dipinhora committed Jun 5, 2018
1 parent 12ada49 commit c27579b
Show file tree
Hide file tree
Showing 4 changed files with 75 additions and 4 deletions.
38 changes: 34 additions & 4 deletions src/libponyc/pass/syntax.c
Original file line number Diff line number Diff line change
Expand Up @@ -398,9 +398,17 @@ static ast_result_t syntax_entity(pass_opt_t* opt, ast_t* ast,
if(entity_def_index != DEF_TYPEALIAS)
{
// Check referenced traits
if(ast_id(provides) != TK_NONE &&
!check_provides_type(opt, provides, "provides"))
r = AST_ERROR;
if(ast_id(provides) != TK_NONE)
{
if(ast_has_annotation(ast, "nosupertype"))
{
ast_error(opt->check.errors, provides,
"a 'nosupertype' type cannot specify a provides list");
r = AST_ERROR;
} else if(!check_provides_type(opt, provides, "provides")) {
r = AST_ERROR;
}
}
}
else
{
Expand Down Expand Up @@ -1261,6 +1269,21 @@ static bool check_annotation_location(pass_opt_t* opt, ast_t* ast,
"a 'packed' annotation can only appear on a struct declaration");
return false;
}
} else if(strcmp(str, "nosupertype") == 0) {
switch(ast_id(ast_parent(ast)))
{
case TK_CLASS:
case TK_ACTOR:
case TK_PRIMITIVE:
case TK_STRUCT:
break;

default:
ast_error(opt->check.errors, loc,
"a 'nosupertype' annotation can only appear on a concrete type "
"declaration");
return false;
}
}

return true;
Expand Down Expand Up @@ -1417,8 +1440,15 @@ ast_result_t pass_syntax(ast_t** astp, pass_opt_t* options)
}

ast_t* annotation = ast_annotation(ast);

if(annotation != NULL)
r = ast_visit(&annotation, pass_syntax, NULL, options, PASS_SYNTAX);
{
ast_result_t r2 = ast_visit(&annotation, pass_syntax, NULL, options,
PASS_SYNTAX);

if(r2 > r)
r = r2;
}

return r;
}
12 changes: 12 additions & 0 deletions src/libponyc/type/subtype.c
Original file line number Diff line number Diff line change
Expand Up @@ -837,6 +837,18 @@ static bool is_nominal_sub_structural(ast_t* sub, ast_t* super,
pony_assert((sub_pass >= PASS_TRAITS) && (super_pass >= PASS_TRAITS));
(void)sub_pass; (void)super_pass;

if(ast_has_annotation(sub_def, "nosupertype"))
{
if(errorf != NULL)
{
ast_error_frame(errorf, sub,
"%s is not a subtype of %s: it is marked 'nosupertype'",
ast_print_type(sub), ast_print_type(super));
}

return false;
}

if(is_bare(sub) != is_bare(super))
{
if(errorf != NULL)
Expand Down
10 changes: 10 additions & 0 deletions test/libponyc/badpony.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1004,3 +1004,13 @@ TEST_F(BadPonyTest, TypeErrorDuringArrayLiteralInference)
" ExpectX[C].trigger([C; C].values())";
TEST_ERRORS_1(src, "type argument is outside its constraint");
}

TEST_F(BadPonyTest, NosupertypeAnnotationProvides)
{
const char* src =
"trait T\n"

"primitive \\nosupertype\\ P is T";

TEST_ERRORS_1(src, "a 'nosupertype' type cannot specify a provides list");
}
19 changes: 19 additions & 0 deletions test/libponyc/type_check_subtype.cc
Original file line number Diff line number Diff line change
Expand Up @@ -558,6 +558,25 @@ TEST_F(SubTypeTest, IsSubTypeCap)
}


TEST_F(SubTypeTest, IsSubTypeNosupertypeInterface)
{
const char* src =
"primitive \\nosupertype\\ P\n"

"interface Test\n"
" fun z(p: P, a: Any val)";

TEST_COMPILE(src);

pass_opt_t opt;
pass_opt_init(&opt);

ASSERT_FALSE(is_subtype(type_of("p"), type_of("a"), NULL, &opt));

pass_opt_init(&opt);
}


TEST_F(SubTypeTest, IsEqType)
{
const char* src =
Expand Down

0 comments on commit c27579b

Please sign in to comment.