summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2020-03-04 12:55:36 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2020-03-04 12:55:36 -0500
commitbe38befebb0ae722f23c069b414e6bf8103e2b3d (patch)
tree02ba5a050c3f5ac2a0439680006efdfae43ef0e2
parent39e5e4fbb83188eafde2c7c5822b33ff451fadd8 (diff)
infer error messages are now somewhat good
-rw-r--r--infer.c72
-rw-r--r--types.c6
2 files changed, 39 insertions, 39 deletions
diff --git a/infer.c b/infer.c
index a6cf34b..e895251 100644
--- a/infer.c
+++ b/infer.c
@@ -31,50 +31,46 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
}
break;
case EXPR_CALL: {
- if (to->kind == EXPR_TYPE && to->typeval->kind == TYPE_STRUCT) {
- /* maybe it's a parameterized struct? */
- /* it might not be possible that it's not, but might as well keep that possibility around. */
- Value fn_val = {0};
- if (!types_expr(tr, match->call.fn)) {
+ if (!types_expr(tr, match->call.fn))
+ return false;
+ if (type_is_builtin(&match->call.fn->type, BUILTIN_TYPE)) {
+ /* it's a parameterized struct */
+ Value fn_val;
+ if (!eval_expr(tr->evalr, to, &fn_val))
+ return false;
+ if (!type_is_builtin(&to->type, BUILTIN_TYPE) || fn_val.type->kind != TYPE_STRUCT) {
+ err_print(to->where, "Wrong argument type. Expected this to be a struct, but it's not.");
+ info_print(match->where, "Parameter was declared here.");
return false;
}
- if (type_is_builtin(&match->call.fn->type, BUILTIN_TYPE)) {
- /* it's a parameterized struct */
- if (!eval_expr(tr->evalr, match->call.fn, &fn_val)) {
- return false;
- }
-
- assert(fn_val.type->kind == TYPE_STRUCT);
-
- I16 *order;
- if (!parameterized_struct_arg_order(fn_val.type->struc, match->call.args, &order, match->where)) {
- free(order);
- return false;
- }
- Declaration *params = to->typeval->struc->params;
- int arg_idx = 0;
- arr_foreach(params, Declaration, param) {
- int ident_idx = 0;
- arr_foreach(param->idents, Identifier, i) {
- if (order[arg_idx] != -1) {
- Expression *arg = &match->call.args[order[arg_idx]].val;
- Value val = *decl_val_at_index(param, ident_idx);
- Expression val_expr = {0};
- val_expr.kind = EXPR_VAL;
- val_expr.val = val;
- val_expr.type = *decl_type_at_index(param, ident_idx);
- val_expr.flags = EXPR_FOUND_TYPE;
- if (!infer_from_expr(tr, arg, &val_expr, idents, vals, types)) {
- free(order);
- return false;
- }
+ I16 *order;
+ if (!parameterized_struct_arg_order(fn_val.type->struc, match->call.args, &order, match->where)) {
+ free(order);
+ return false;
+ }
+ Declaration *params = to->typeval->struc->params;
+ int arg_idx = 0;
+ arr_foreach(params, Declaration, param) {
+ int ident_idx = 0;
+ arr_foreach(param->idents, Identifier, i) {
+ if (order[arg_idx] != -1) {
+ Expression *arg = &match->call.args[order[arg_idx]].val;
+ Value val = *decl_val_at_index(param, ident_idx);
+ Expression val_expr = {0};
+ val_expr.kind = EXPR_VAL;
+ val_expr.val = val;
+ val_expr.type = *decl_type_at_index(param, ident_idx);
+ val_expr.flags = EXPR_FOUND_TYPE;
+ if (!infer_from_expr(tr, arg, &val_expr, idents, vals, types)) {
+ free(order);
+ return false;
}
- ++arg_idx;
- ++ident_idx;
}
+ ++arg_idx;
+ ++ident_idx;
}
- free(order);
}
+ free(order);
}
while (to->kind == EXPR_IDENT) {
diff --git a/types.c b/types.c
index 1089d55..18064ff 100644
--- a/types.c
+++ b/types.c
@@ -661,6 +661,10 @@ static Status type_of_ident(Typer *tr, Location where, Identifier *ident, Type *
info_print(d->where, "%s will be declared here.", s);
free(s);
} else {
+ if (d->flags & DECL_INFER) {
+ err_print(where, "Use of identifier before it has been inferred. You are trying to do stuff with inference which toc doesn't support.");
+ return false;
+ }
/* let's type the declaration, and redo this (for evaling future functions) */
if (!types_decl(tr, d)) return false;
return type_of_ident(tr, where, ident, t);
@@ -2018,7 +2022,7 @@ static Status types_expr(Typer *tr, Expression *e) {
}
err_print(decl->where, "Could not infer value of declaration.");
info_print(e->where, "While processing this call");
- return false;
+ return false;
}
++type;
}