mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 15:48:51 +00:00
Better error messages
This commit is contained in:
+7
-7
@@ -2424,27 +2424,27 @@ gb_internal void check_assignment_error_suggestion(CheckerContext *c, Operand *o
|
|||||||
Type *s = src->Array.elem;
|
Type *s = src->Array.elem;
|
||||||
Type *d = dst->Slice.elem;
|
Type *d = dst->Slice.elem;
|
||||||
if (are_types_identical(s, d)) {
|
if (are_types_identical(s, d)) {
|
||||||
error_line("\tSuggestion: the array expression may be sliced with %s[:]\n", a);
|
error_line("\tSuggestion: The array expression may be sliced with %s[:]\n", a);
|
||||||
}
|
}
|
||||||
} else if (is_type_dynamic_array(src) && is_type_slice(dst)) {
|
} else if (is_type_dynamic_array(src) && is_type_slice(dst)) {
|
||||||
Type *s = src->DynamicArray.elem;
|
Type *s = src->DynamicArray.elem;
|
||||||
Type *d = dst->Slice.elem;
|
Type *d = dst->Slice.elem;
|
||||||
if (are_types_identical(s, d)) {
|
if (are_types_identical(s, d)) {
|
||||||
error_line("\tSuggestion: the dynamic array expression may be sliced with %s[:]\n", a);
|
error_line("\tSuggestion: The dynamic array expression may be sliced with %s[:]\n", a);
|
||||||
}
|
}
|
||||||
}else if (are_types_identical(src, dst) && !are_types_identical(o->type, type)) {
|
}else if (are_types_identical(src, dst) && !are_types_identical(o->type, type)) {
|
||||||
error_line("\tSuggestion: the expression may be directly casted to type %s\n", b);
|
error_line("\tSuggestion: The expression may be directly casted to type %s\n", b);
|
||||||
} else if (are_types_identical(src, t_string) && is_type_u8_slice(dst)) {
|
} else if (are_types_identical(src, t_string) && is_type_u8_slice(dst)) {
|
||||||
error_line("\tSuggestion: a string may be transmuted to %s\n", b);
|
error_line("\tSuggestion: A string may be transmuted to %s\n", b);
|
||||||
error_line("\t This is an UNSAFE operation as string data is assumed to be immutable, \n");
|
error_line("\t This is an UNSAFE operation as string data is assumed to be immutable,\n");
|
||||||
error_line("\t whereas slices in general are assumed to be mutable.\n");
|
error_line("\t whereas slices in general are assumed to be mutable.\n");
|
||||||
} else if (is_type_u8_slice(src) && are_types_identical(dst, t_string) && o->mode != Addressing_Constant) {
|
} else if (is_type_u8_slice(src) && are_types_identical(dst, t_string) && o->mode != Addressing_Constant) {
|
||||||
error_line("\tSuggestion: the expression may be casted to %s\n", b);
|
error_line("\tSuggestion: The expression may be casted to %s\n", b);
|
||||||
} else if (check_integer_exceed_suggestion(c, o, type, max_bit_size)) {
|
} else if (check_integer_exceed_suggestion(c, o, type, max_bit_size)) {
|
||||||
return;
|
return;
|
||||||
} else if (is_expr_inferred_fixed_array(c->type_hint_expr) && is_type_array_like(type) && is_type_array_like(o->type)) {
|
} else if (is_expr_inferred_fixed_array(c->type_hint_expr) && is_type_array_like(type) && is_type_array_like(o->type)) {
|
||||||
gbString s = expr_to_string(c->type_hint_expr);
|
gbString s = expr_to_string(c->type_hint_expr);
|
||||||
error_line("\tSuggestion: make sure that `%s` is attached to the compound literal directly\n", s);
|
error_line("\tSuggestion: Make sure that `%s` is attached to the compound literal directly\n", s);
|
||||||
gb_string_free(s);
|
gb_string_free(s);
|
||||||
} else if (is_type_pointer(type) &&
|
} else if (is_type_pointer(type) &&
|
||||||
o->mode == Addressing_Variable &&
|
o->mode == Addressing_Variable &&
|
||||||
|
|||||||
+11
-9
@@ -418,7 +418,7 @@ gb_internal bool check_is_terminating(Ast *node, String const &label) {
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs) {
|
gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, Operand *rhs, String context_name) {
|
||||||
if (rhs->mode == Addressing_Invalid) {
|
if (rhs->mode == Addressing_Invalid) {
|
||||||
return nullptr;
|
return nullptr;
|
||||||
}
|
}
|
||||||
@@ -430,7 +430,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
|
|||||||
|
|
||||||
Ast *node = unparen_expr(lhs->expr);
|
Ast *node = unparen_expr(lhs->expr);
|
||||||
|
|
||||||
check_no_copy_assignment(*rhs, str_lit("assignment"));
|
check_no_copy_assignment(*rhs, context_name);
|
||||||
|
|
||||||
// NOTE(bill): Ignore assignments to '_'
|
// NOTE(bill): Ignore assignments to '_'
|
||||||
if (is_blank_ident(node)) {
|
if (is_blank_ident(node)) {
|
||||||
@@ -630,7 +630,7 @@ gb_internal Type *check_assignment_variable(CheckerContext *ctx, Operand *lhs, O
|
|||||||
ctx->bit_field_bit_size = lhs_e->Variable.bit_field_bit_size;
|
ctx->bit_field_bit_size = lhs_e->Variable.bit_field_bit_size;
|
||||||
}
|
}
|
||||||
|
|
||||||
check_assignment(ctx, rhs, assignment_type, str_lit("assignment"));
|
check_assignment(ctx, rhs, assignment_type, context_name);
|
||||||
|
|
||||||
ctx->bit_field_bit_size = prev_bit_field_bit_size;
|
ctx->bit_field_bit_size = prev_bit_field_bit_size;
|
||||||
|
|
||||||
@@ -2418,7 +2418,7 @@ gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
|||||||
|
|
||||||
isize lhs_count = as->lhs.count;
|
isize lhs_count = as->lhs.count;
|
||||||
if (lhs_count == 0) {
|
if (lhs_count == 0) {
|
||||||
error(as->op, "Missing lhs in assignment statement");
|
error(as->op, "Missing LHS in assignment statement");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2451,7 +2451,7 @@ gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
|||||||
if (lhs_to_ignore[i]) {
|
if (lhs_to_ignore[i]) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
check_assignment_variable(ctx, &lhs_operands[i], &rhs_operands[i]);
|
check_assignment_variable(ctx, &lhs_operands[i], &rhs_operands[i], str_lit("assignment"));
|
||||||
}
|
}
|
||||||
if (lhs_count != rhs_count) {
|
if (lhs_count != rhs_count) {
|
||||||
error(as->lhs[0], "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
|
error(as->lhs[0], "Assignment count mismatch '%td' = '%td'", lhs_count, rhs_count);
|
||||||
@@ -2461,11 +2461,11 @@ gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
|||||||
// a += 1; // Single-sided
|
// a += 1; // Single-sided
|
||||||
Token op = as->op;
|
Token op = as->op;
|
||||||
if (as->lhs.count != 1 || as->rhs.count != 1) {
|
if (as->lhs.count != 1 || as->rhs.count != 1) {
|
||||||
error(op, "Assignment operation '%.*s' requires single-valued expressions", LIT(op.string));
|
error(op, "Assignment operator '%.*s' requires single-valued operands", LIT(op.string));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!gb_is_between(op.kind, Token__AssignOpBegin+1, Token__AssignOpEnd-1)) {
|
if (!gb_is_between(op.kind, Token__AssignOpBegin+1, Token__AssignOpEnd-1)) {
|
||||||
error(op, "Unknown Assignment operation '%.*s'", LIT(op.string));
|
error(op, "Unknown assignment operator '%.*s'", LIT(op.string));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Operand lhs = {Addressing_Invalid};
|
Operand lhs = {Addressing_Invalid};
|
||||||
@@ -2474,7 +2474,7 @@ gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
|||||||
ast_node(be, BinaryExpr, binary_expr);
|
ast_node(be, BinaryExpr, binary_expr);
|
||||||
be->op = op;
|
be->op = op;
|
||||||
be->op.kind = cast(TokenKind)(cast(i32)be->op.kind - (Token_AddEq - Token_Add));
|
be->op.kind = cast(TokenKind)(cast(i32)be->op.kind - (Token_AddEq - Token_Add));
|
||||||
// NOTE(bill): Only use the first one will be used
|
// NOTE(bill): Only use the first one will be used
|
||||||
be->left = as->lhs[0];
|
be->left = as->lhs[0];
|
||||||
be->right = as->rhs[0];
|
be->right = as->rhs[0];
|
||||||
|
|
||||||
@@ -2482,7 +2482,9 @@ gb_internal void check_assign_stmt(CheckerContext *ctx, Ast *node) {
|
|||||||
check_binary_expr(ctx, &rhs, binary_expr, nullptr, true);
|
check_binary_expr(ctx, &rhs, binary_expr, nullptr, true);
|
||||||
if (rhs.mode != Addressing_Invalid) {
|
if (rhs.mode != Addressing_Invalid) {
|
||||||
// NOTE(bill): Only use the first one will be used
|
// NOTE(bill): Only use the first one will be used
|
||||||
check_assignment_variable(ctx, &lhs, &rhs);
|
be->op.string = substring(be->op.string, 0, 1);
|
||||||
|
rhs.expr = binary_expr;
|
||||||
|
check_assignment_variable(ctx, &lhs, &rhs, str_lit("assignment operation"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user