aboutsummaryrefslogtreecommitdiff
path: root/src/check_type.cpp
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2022-07-11 12:31:01 +0100
committergingerBill <bill@gingerbill.org>2022-07-11 12:31:01 +0100
commit37d04198ab73441510a8556abd1aa1b5a4615c9b (patch)
tree346479e4c902cd844ff27f7f0eecf84787b83f37 /src/check_type.cpp
parent9e376fbda75970b6cafa229873bfe8113da251d6 (diff)
Add improved error message when doing `^x` instead of `&x` for addressable variables
Diffstat (limited to 'src/check_type.cpp')
-rw-r--r--src/check_type.cpp23
1 files changed, 22 insertions, 1 deletions
diff --git a/src/check_type.cpp b/src/check_type.cpp
index bc89a9be9..cd4b43fab 100644
--- a/src/check_type.cpp
+++ b/src/check_type.cpp
@@ -2685,7 +2685,28 @@ bool check_type_internal(CheckerContext *ctx, Ast *e, Type **type, Type *named_t
case_end;
case_ast_node(pt, PointerType, e);
- *type = alloc_type_pointer(check_type(ctx, pt->type));
+ CheckerContext c = *ctx;
+ c.type_path = new_checker_type_path();
+ defer (destroy_checker_type_path(c.type_path));
+
+ Type *elem = t_invalid;
+ Operand o = {};
+ check_expr_or_type(&c, &o, pt->type);
+ if (o.mode != Addressing_Invalid && o.mode != Addressing_Type) {
+ // NOTE(bill): call check_type_expr again to get a consistent error message
+ begin_error_block();
+ elem = check_type_expr(&c, pt->type, nullptr);
+ if (o.mode == Addressing_Variable) {
+ gbString s = expr_to_string(pt->type);
+ error_line("\tSuggestion: ^ is used for pointer types, did you mean '&%s'?\n", s);
+ gb_string_free(s);
+ }
+ end_error_block();
+ } else {
+ elem = o.type;
+ }
+
+ *type = alloc_type_pointer(elem);
set_base_type(named_type, *type);
return true;
case_end;