Skip to content

Commit

Permalink
Disallow trying to autorecover to a complex type
Browse files Browse the repository at this point in the history
  • Loading branch information
chalcolith committed Jun 10, 2022
1 parent a804a0e commit 2c5535c
Show file tree
Hide file tree
Showing 3 changed files with 26 additions and 1 deletion.
2 changes: 2 additions & 0 deletions .release-notes/4124.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,3 +20,5 @@ primitive Bar
You'd get compilation errors "argument not assignable to parameter" and "right side must be a subtype of left side" for the two lines in `Main.create()`.

We've added checks to see if the constructor expressions can be implicitly auto-recovered, and if they can, no compilation error is generated.

This only applies to cases where the type of the parameter (or the `let` binding) is a simple type, i.e. not a union, intersection or tuple type.
6 changes: 5 additions & 1 deletion src/libponyc/expr/call.c
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,10 @@ static ast_t* method_receiver_type(ast_t* method);

bool check_auto_recover_newref(ast_t* param_type, ast_t* ast)
{
// we're not going to try auto-recovering to a complex type
if (ast_id(param_type) != TK_NOMINAL)
return false;

while (ast != NULL && ast_id(ast) != TK_CALL)
ast = ast_child(ast);

Expand All @@ -208,7 +212,7 @@ bool check_auto_recover_newref(ast_t* param_type, ast_t* ast)
if (ast_id(newref) != TK_NEWREF)
return false;

// sometimes newrefs are nested?
// sometimes for assignments there's a nested newref
ast_t* child = ast_child(newref);
if (child != NULL && ast_id(child) == TK_NEWREF)
newref = child;
Expand Down
19 changes: 19 additions & 0 deletions test/libponyc/recover.cc
Original file line number Diff line number Diff line change
Expand Up @@ -778,3 +778,22 @@ TEST_F(RecoverTest, CantAutoRecover_CtorAssignmentWithNonSendableArg)

TEST_ERRORS_1(src, "right side must be a subtype of left side");
}
TEST_F(RecoverTest, CantAutoRecover_CtorParamToComplexTypeWithNonSendableArg)
{
const char* src =
"actor Main\n"
" new create(env: Env) =>\n"
" let bar: (Foo iso | String ref) = Foo.from_u8(123)\n"

"class Foo\n"
" new from_u8(v: U8) =>\n"
" None\n"
" new from_str(s: String ref) =>\n"
" None\n"

"primitive Bar\n"
" fun take_foo(foo: Foo iso) =>\n"
" None\n";

TEST_ERRORS_1(src, "right side must be a subtype of left side");
}

0 comments on commit 2c5535c

Please sign in to comment.