Add better typechecking for Abort (and add Abort
as a user-reachable
type) and check for unreachable code
This commit is contained in:
parent
6abd4e8024
commit
94ed28b4d1
@ -4108,8 +4108,12 @@ CORD compile_function(env_t *env, ast_t *ast, CORD *staticdefs)
|
||||
body_scope->fn_ret = ret_t;
|
||||
|
||||
type_t *body_type = get_type(body_scope, fndef->body);
|
||||
if (ret_t->tag != VoidType && ret_t->tag != AbortType && body_type->tag != AbortType && body_type->tag != ReturnType)
|
||||
if (ret_t->tag == AbortType) {
|
||||
if (body_type->tag != AbortType)
|
||||
code_err(ast, "This function can reach the end without aborting!");
|
||||
} else if (ret_t->tag != VoidType && body_type->tag != ReturnType) {
|
||||
code_err(ast, "This function can reach the end without returning a %T value!", ret_t);
|
||||
}
|
||||
|
||||
CORD body = compile_statement(body_scope, fndef->body);
|
||||
if (streq(raw_name, "main"))
|
||||
|
@ -99,6 +99,7 @@ env_t *new_compilation_unit(CORD libname)
|
||||
Array_t namespace;
|
||||
} global_types[] = {
|
||||
{"Void", Type(VoidType), "Void_t", "Void$info", {}},
|
||||
{"Abort", Type(AbortType), "void", "Abort$info", {}},
|
||||
{"Memory", Type(MemoryType), "Memory_t", "Memory$info", {}},
|
||||
{"Bool", Type(BoolType), "Bool_t", "Bool$info", TypedArray(ns_entry_t,
|
||||
{"parse", "Bool$parse", "func(text:Text -> Bool?)"},
|
||||
|
10
typecheck.c
10
typecheck.c
@ -920,8 +920,18 @@ type_t *get_type(env_t *env, ast_t *ast)
|
||||
}
|
||||
|
||||
env_t *block_env = fresh_scope(env);
|
||||
for (ast_list_t *stmt = block->statements; stmt; stmt = stmt->next) {
|
||||
prebind_statement(block_env, stmt->ast);
|
||||
}
|
||||
for (ast_list_t *stmt = block->statements; stmt; stmt = stmt->next) {
|
||||
bind_statement(block_env, stmt->ast);
|
||||
if (stmt->next) { // Check for unreachable code:
|
||||
if (stmt->ast->tag == Return)
|
||||
code_err(stmt->ast, "This statement will always return, so the rest of the code in this block is unreachable!");
|
||||
type_t *statement_type = get_type(block_env, stmt->ast);
|
||||
if (statement_type && statement_type->tag == AbortType && stmt->next)
|
||||
code_err(stmt->ast, "This statement will always abort, so the rest of the code in this block is unreachable!");
|
||||
}
|
||||
}
|
||||
return get_type(block_env, last->ast);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user