Fix return type checking bug due to tuples potentially having untyped types. Also working on down typing untyped.

This commit is contained in:
Krzosa Karol
2022-06-22 11:18:00 +02:00
parent de159fc7d9
commit 40557b083b
2 changed files with 42 additions and 15 deletions

View File

@@ -154,7 +154,9 @@ gen_string_simple_decl(Allocator *a, Ast_Type *ast, String name){
}
function B32
gen_value(Value a){
gen_value(Token *pos, Value a){
if(is_untyped(a.type)) compiler_error(pos, "Internal compiler error: Untyped got propagated to the codegen stage");
B32 result = true;
if(is_enum(a.type))
goto integer;
@@ -275,12 +277,12 @@ gen_expr(Ast_Expr *ast, Ast_Type *type_of_var){
CASE(VALUE, Atom){
if(is_any(type_of_var)){
gen("(Any){&");
gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->value); gen("}");
gen("("); gen_simple_decl(node->type); gen("){"); gen_value(node->pos, node->value); gen("}");
gen(", %d}", node->type->type_id);
return true;
}
B32 written = gen_value(node->value);
B32 written = gen_value(node->pos, node->value);
if(!written) {
gen("%Q", node->value.intern_val);
}
@@ -586,7 +588,7 @@ gen_ast(Ast *ast){
For(node->scope->decls){
genln("%Q", it->name);
gen(" = ");
gen_value(it->value);
gen_value(it->pos, it->value);
gen(",");
}
global_indent--;
@@ -598,20 +600,20 @@ gen_ast(Ast *ast){
switch(node->type->kind){
CASE_FLOAT:{
gen("// F64 %Q = ", node->name);
gen_value(node->value);
// gen_value(node->pos, node->value);
} break;
CASE_INT:{
gen("// constant int %Q = ", node->name);
gen_value(node->value);
// gen_value(node->pos, node->value);
}break;
CASE_STRING:{
assert(is_pointer(node->type) ? node->type == type_pointer_to_char : 1);
gen("// const String %Q = ", node->name);
gen_value(node->value);
// gen_value(node->pos, node->value);
}break;
CASE_BOOL:{
gen("// const Bool %Q = ", node->name);
gen_value(node->value);
// gen_value(node->pos, node->value);
}break;
case TYPE_LAMBDA:{
gen("// ");

View File

@@ -516,18 +516,31 @@ resolve_stmt(Ast *ast, Ast_Type *ret){
CASE(RETURN, Return){ // @todo: need to check if all paths return a value
Scratch scratch;
Array<Ast_Type *> types = {scratch};
For(node->expr){
Operand op = resolve_expr(it, AST_CAN_BE_NULL);
For_It(node->expr){
Operand op;
if(is_tuple(ret)){
Ast_Type *sub_type = ret->agg.members[it.i].type;
op = resolve_expr(*it.it, AST_CAN_BE_NULL, sub_type);
}
else{
op = resolve_expr(*it.it, AST_CAN_BE_NULL, ret);
op.value = convert_untyped_to_typed(node->pos, op.value, ret);
}
types.add(op.type);
}
Ast_Type *type = type_try_tupling(types, node);
Value value = {}; value.type = type;
value = convert_untyped_to_typed(node->pos, value, ret);
if(value.type && value.type != ret)
if(type && type != ret)
compiler_error(node->pos, "Return statement has different type then returned value, expecting: %Q got instead %Q", typestring(ret), typestring(type));
node->resolved_type = value.type;
node->resolved_type = type;
// @todo down untyping
// For_It(node->expr){
// Ast_Type *type =
// }
BREAK();
}
@@ -884,6 +897,15 @@ resolve_field_access(Ast_Expr *node, Ast_Scope *context){
return resolve_field_access(next, ((Ast_Decl *)type->ast)->scope);
}
function void
try_propagating_resolved_type_to_untyped_literals_one_level_deep(Ast *ast, Ast_Type *type){
if(ast->kind != AST_VALUE) return;
if(is_untyped(type)) return;
auto node = (Ast_Atom *)ast;
convert_untyped_to_typed(ast->pos, node->value, type);// @rename: try and this
}
function Operand
resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
if(!ast && is_flag_set(flags, AST_CAN_BE_NULL)) return {};
@@ -978,6 +1000,9 @@ resolve_expr(Ast_Expr *ast, Resolve_Flag flags, Ast_Type *compound_context){
right.value = convert_untyped_to_typed(node->pos, right.value, left.type);
if(left.type != right.type) compiler_error(node->pos, "Can't assign value when left is %Q and right is %Q", typestring(left.type), typestring(right.type));
node->resolved_type = right.type;
try_propagating_resolved_type_to_untyped_literals_one_level_deep(node->left, node->resolved_type);
try_propagating_resolved_type_to_untyped_literals_one_level_deep(node->left, node->resolved_type);
return {};
}
else if(node->op == TK_Arrow){