Skip to content

Commit

Permalink
improved error for match over union of different capabilities (#1516)
Browse files Browse the repository at this point in the history
  • Loading branch information
Theodus authored and sylvanc committed Jan 18, 2017
1 parent 3dfab96 commit 8daa6ef
Show file tree
Hide file tree
Showing 2 changed files with 43 additions and 6 deletions.
26 changes: 20 additions & 6 deletions src/libponyc/expr/match.c
Original file line number Diff line number Diff line change
Expand Up @@ -333,12 +333,26 @@ bool expr_case(pass_opt_t* opt, ast_t* ast)

case MATCHTYPE_DENY:
{
ast_error(opt->check.errors, pattern,
"this capture violates capabilities");
ast_error_continue(opt->check.errors, match_type, "match type: %s",
ast_print_type(operand_type));
ast_error_continue(opt->check.errors, pattern, "pattern type: %s",
ast_print_type(pattern_type));
if(ast_id(match_type) == TK_UNIONTYPE) {
token_id cap = ast_id(ast_childidx(ast_child(match_type), 3));
for(size_t i=1; i<ast_childcount(match_type); i++) {
if(ast_id(ast_childidx(ast_childidx(match_type, i), 3)) != cap) {
ast_error(opt->check.errors, match_expr,
"match type may not be a union of types with different "
"capabilities");
ast_error_continue(opt->check.errors, match_type, "match type: %s",
ast_print_type(operand_type));
}
}
} else {
ast_error(opt->check.errors, pattern,
"this capture violates capabilities");
ast_error_continue(opt->check.errors, match_type, "match type: %s",
ast_print_type(operand_type));
ast_error_continue(opt->check.errors, pattern, "pattern type: %s",
ast_print_type(pattern_type));
}

ok = false;
break;
}
Expand Down
23 changes: 23 additions & 0 deletions test/libponyc/badpony.cc
Original file line number Diff line number Diff line change
Expand Up @@ -315,3 +315,26 @@ TEST_F(BadPonyTest, IndexArrayWithBrackets)

TEST_ERRORS_1(src, "Value formal parameters not yet supported");
}

TEST_F(BadPonyTest, MatchUnionOfDifferentCaps)
{
// From issue #1506
const char* src =
"interface box Foo\n"
"fun foo(): None\n"

"interface ref Bar\n"
"fun ref bar(): None\n"

"actor Main\n"
"new create(env: Env) => None\n"

"fun apply(x: (Foo | Bar)) =>\n"
"match x\n"
"| let f: Foo => f.foo()\n"
"| let b: Bar => b.bar()\n"
"end";

TEST_ERRORS_1(src,
"match type may not be a union of types with different capabilities");
}

0 comments on commit 8daa6ef

Please sign in to comment.