From 02eea15b92745cd10c325722236cc9e4f420bb71 Mon Sep 17 00:00:00 2001 From: gingerBill Date: Thu, 6 Mar 2025 10:02:49 +0000 Subject: [PATCH] Add `Did you mean` for wrong `case`/type-assert type. --- src/check_expr.cpp | 14 ++++++++++++++ src/check_stmt.cpp | 14 ++++++++++++++ src/llvm_backend_type.cpp | 15 ++++----------- 3 files changed, 32 insertions(+), 11 deletions(-) diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 2f7b5fd0a..cf57b8c83 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -10410,6 +10410,8 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no } if (!ok) { + ERROR_BLOCK(); + gbString expr_str = expr_to_string(o->expr); gbString dst_type_str = type_to_string(t); defer (gb_string_free(expr_str)); @@ -10418,6 +10420,18 @@ gb_internal ExprKind check_type_assertion(CheckerContext *c, Operand *o, Ast *no error(o->expr, "Cannot type assert '%s' to '%s' as this is an empty union", expr_str, dst_type_str); } else { error(o->expr, "Cannot type assert '%s' to '%s' as it is not a variant of that union", expr_str, dst_type_str); + + for (Type *vt : bsrc->Union.variants) { + Type *xt = type_deref(vt); + Type *yt = type_deref(t); + if (are_types_identical(xt, yt)) { + gbString s = type_to_string(vt); + error_line("\tDid you mean: '%s'?", s); + gb_string_free(s); + break; + } + } + } o->mode = Addressing_Invalid; o->expr = node; diff --git a/src/check_stmt.cpp b/src/check_stmt.cpp index e81996566..ae7168661 100644 --- a/src/check_stmt.cpp +++ b/src/check_stmt.cpp @@ -1501,9 +1501,23 @@ gb_internal void check_type_switch_stmt(CheckerContext *ctx, Ast *node, u32 mod_ } } if (!tag_type_found) { + ERROR_BLOCK(); + gbString type_str = type_to_string(y.type); error(y.expr, "Unknown variant type, got '%s'", type_str); gb_string_free(type_str); + + for (Type *vt : bt->Union.variants) { + Type *xt = type_deref(vt); + Type *yt = type_deref(y.type); + if (are_types_identical(xt, yt)) { + gbString s = type_to_string(vt); + error_line("\tDid you mean: '%s'?", s); + gb_string_free(s); + break; + } + } + continue; } case_type = y.type; diff --git a/src/llvm_backend_type.cpp b/src/llvm_backend_type.cpp index 62e30a1b6..49aca89e7 100644 --- a/src/llvm_backend_type.cpp +++ b/src/llvm_backend_type.cpp @@ -856,17 +856,10 @@ gb_internal void lb_setup_type_info_data_giant_array(lbModule *m, i64 global_typ small_const_values[1] = LLVMConstInt(lb_type(m, t_int), align, true); small_const_values[2] = type_info_flags.value; - unsigned variant_index = 0; - if (build_context.ptr_size == 8) { - LLVMTypeRef base_type_info_type = LLVMStructGetTypeAtIndex(stype, 0); - small_const_values[3] = LLVMConstNull(LLVMStructGetTypeAtIndex(base_type_info_type, 3)); - small_const_values[4] = id.value; - variant_index = 5; - } else { - small_const_values[3] = id.value; - variant_index = 4; - } - + unsigned variant_index = 5; + LLVMTypeRef base_type_info_type = LLVMStructGetTypeAtIndex(stype, 0); + small_const_values[3] = LLVMConstNull(LLVMStructGetTypeAtIndex(base_type_info_type, 3)); + small_const_values[4] = id.value; i64 tag_index = 0; if (tag_type != nullptr) {