-
-
Notifications
You must be signed in to change notification settings - Fork 419
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Compiler doesn't see required assignment in try..else structure. #3283
Comments
Here is a more minimal example, exhibiting the same bug. actor Main
var _s: (String | None)
new create(env: Env) =>
try
_s = "".usize()?.string()
else
_s = None
end |
As I am exploring the reason for this, there is more cases exhibiting the same behaviour.
actor Main
var _s: (String | None)
new create(env: Env) =>
var i: USize = 0
while i < 5 do
_s = i.string()
i = i + 1
else
_s = ""
end The same is true for |
This error is because SYM_DEFINED isn't set for the |
This change to static bool refer_while(pass_opt_t* opt, ast_t* ast)
{
pony_assert(ast_id(ast) == TK_WHILE);
AST_GET_CHILDREN(ast, cond, body, else_clause);
// All consumes have to be in scope when the loop body finishes.
errorframe_t errorf = NULL;
if(!ast_all_consumes_in_scope(body, body, &errorf))
{
errorframe_report(&errorf, opt->check.errors);
return false;
}
size_t branch_count = 0;
if(!ast_checkflag(else_clause, AST_FLAG_JUMPS_AWAY))
{
branch_count++;
ast_inheritbranch(ast, body);
ast_consolidate_branches(ast, branch_count);
}
// If all branches jump away with no value, then we do too.
if(branch_count == 0 && ast_checkflag(body, AST_FLAG_JUMPS_AWAY))
ast_setflag(ast, AST_FLAG_JUMPS_AWAY);
// Push our symbol status to our parent scope.
ast_inheritstatus(ast_parent(ast), ast);
return true;
} that leave |
The |
Previously, due to a bug in the compile's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => var i: USize = 0 while i < 5 do _s = i.string() i = i + 1 else _s = "" end ``` This commit fixes while/else handling in `refer_while` so that it matches the correct logic as seen in `refer_if`. Partially addresses a series of related bugs in #3283.
Previously, due to a bug in the compile's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => var i: USize = 0 while i < 5 do _s = i.string() i = i + 1 else _s = "" end ``` This commit fixes while/else handling in `refer_while` so that it matches the correct logic as seen in `refer_if`. Partially addresses a series of related bugs in #3283.
|
So the issue with try appears to be that unlike if and while etc, if doesn't introduce a scope and without it, there's no symbol table. Not sure why that is. I don't believe this is possible to fix without I'm also not sure why |
Ok I figured out how to fix this and I think in the process I understand why |
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => try _s = "".usize()?.string() else _s = None end ``` This commit fixes try/else handling in `refer_try` so that it matches the general shape of `refer_if`, `refer_while`, and `refer_repeat`. It differs from them because `try` isn't a scope and we want to push everything into the `then` clause as it can fulfill initialization all on its own or if it doesn't handle initialization, we can still get it from the try body and the else clause. Closes #3283
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => try _s = "".usize()?.string() else _s = None end ``` This commit fixes try/else handling in `refer_try` so that it matches the general shape of `refer_if`, `refer_while`, and `refer_repeat`. It differs from them because `try` isn't a scope and we want to push everything into the `then` clause as it can fulfill initialization all on its own or if it doesn't handle initialization, we can still get it from the try body and the else clause. Closes #3283
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => var i: USize = 0 while i < 5 do _s = i.string() i = i + 1 else _s = "" end ``` This commit fixes while/else handling in `refer_while` so that it matches the correct logic as seen in `refer_if`. Partially addresses a series of related bugs in #3283.
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => var i: USize = 0 while i < 5 do _s = i.string() i = i + 1 else _s = "" end ``` This commit fixes while/else handling in `refer_while` so that it matches the correct logic as seen in `refer_if`. Partially addresses a series of related bugs in #3283.
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => try _s = "".usize()?.string() else _s = None end ``` This commit fixes try/else handling in `refer_try` so that it matches the general shape of `refer_if`, `refer_while`, and `refer_repeat`. It differs from them because `try` isn't a scope and we want to push everything into the `then` clause as it can fulfill initialization all on its own or if it doesn't handle initialization, we can still get it from the try body and the else clause. Closes #3283
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => try _s = "".usize()?.string() else _s = None end ``` This commit fixes try/else handling in `refer_try` so that it matches the general shape of `refer_if`, `refer_while`, and `refer_repeat`. It differs from them because `try` isn't a scope and we want to push everything into the `then` clause as it can fulfill initialization all on its own or if it doesn't handle initialization, we can still get it from the try body and the else clause. Closes #3283
Previously, due to a bug in the compiler's while/else handling code, the following code would be rejected as not initializing all object fields: ```pony actor Main var _s: (String | None) new create(env: Env) => try _s = "".usize()?.string() else _s = None end ``` This commit fixes try/else handling in `refer_try` so that it matches the general shape of `refer_if`, `refer_while`, and `refer_repeat`. It differs from them because `try` isn't a scope and we want to push everything into the `then` clause as it can fulfill initialization all on its own or if it doesn't handle initialization, we can still get it from the try body and the else clause. Closes #3283
The sample https://playground.ponylang.io/?gist=8b8975e6007b92a892779ac8f6a838ac doesn't compile, even though
_tcp
is being assigned in both branches.Perhaps there are additional/hidden branches that I am unaware of.
The text was updated successfully, but these errors were encountered: