mirror of
https://github.com/odin-lang/Odin.git
synced 2026-01-09 06:23:14 +00:00
Remove the old switch/for semantics entirely and enforce switch &x in y
This commit is contained in:
@@ -2440,32 +2440,6 @@ gb_internal bool check_is_not_addressable(CheckerContext *c, Operand *o) {
|
||||
return o->mode != Addressing_Variable && o->mode != Addressing_SoaVariable;
|
||||
}
|
||||
|
||||
gb_internal void check_old_for_or_switch_value_usage(Ast *expr) {
|
||||
Entity *e = entity_of_node(expr);
|
||||
if (e != nullptr && (e->flags & EntityFlag_OldForOrSwitchValue) != 0) {
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
|
||||
ERROR_BLOCK();
|
||||
|
||||
if ((e->flags & EntityFlag_ForValue) != 0) {
|
||||
Type *parent_type = type_deref(e->Variable.for_loop_parent_type);
|
||||
|
||||
error(expr, "Assuming a for-in defined value is addressable as the iterable is passed by value has been disallowed.");
|
||||
|
||||
if (is_type_map(parent_type)) {
|
||||
error_line("\tSuggestion: Prefer doing 'for key, &%.*s in ...'\n", LIT(e->token.string));
|
||||
} else {
|
||||
error_line("\tSuggestion: Prefer doing 'for &%.*s in ...'\n", LIT(e->token.string));
|
||||
}
|
||||
} else {
|
||||
GB_ASSERT((e->flags & EntityFlag_SwitchValue) != 0);
|
||||
|
||||
error(expr, "Assuming a switch-in defined value is addressable as the iterable is passed by value has been disallowed.");
|
||||
error_line("\tSuggestion: Prefer doing 'switch &%.*s in ...'\n", LIT(e->token.string));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *node) {
|
||||
switch (op.kind) {
|
||||
case Token_And: { // Pointer address
|
||||
@@ -2493,7 +2467,10 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *
|
||||
{
|
||||
ERROR_BLOCK();
|
||||
error(op, "Cannot take the pointer address of '%s'", str);
|
||||
if (e != nullptr && (e->flags & EntityFlag_ForValue) != 0) {
|
||||
if (e == nullptr) {
|
||||
break;
|
||||
}
|
||||
if ((e->flags & EntityFlag_ForValue) != 0) {
|
||||
Type *parent_type = type_deref(e->Variable.for_loop_parent_type);
|
||||
|
||||
if (parent_type != nullptr && is_type_string(parent_type)) {
|
||||
@@ -2503,9 +2480,17 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *
|
||||
} else {
|
||||
error_line("\tSuggestion: Did you want to pass the iterable value to the for statement by pointer to get addressable semantics?\n");
|
||||
}
|
||||
|
||||
if (is_type_map(parent_type)) {
|
||||
error_line("\t Prefer doing 'for key, &%.*s in ...'\n", LIT(e->token.string));
|
||||
} else {
|
||||
error_line("\t Prefer doing 'for &%.*s in ...'\n", LIT(e->token.string));
|
||||
}
|
||||
}
|
||||
if (e != nullptr && (e->flags & EntityFlag_SwitchValue) != 0) {
|
||||
if ((e->flags & EntityFlag_SwitchValue) != 0) {
|
||||
error_line("\tSuggestion: Did you want to pass the value to the switch statement by pointer to get addressable semantics?\n");
|
||||
|
||||
error_line("\t Prefer doing 'switch &%.*s in ...'\n", LIT(e->token.string));
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -2527,11 +2512,6 @@ gb_internal void check_unary_expr(CheckerContext *c, Operand *o, Token op, Ast *
|
||||
o->type = alloc_type_pointer(o->type);
|
||||
}
|
||||
} else {
|
||||
if (ast_node_expect(node, Ast_UnaryExpr)) {
|
||||
ast_node(ue, UnaryExpr, node);
|
||||
check_old_for_or_switch_value_usage(ue->expr);
|
||||
}
|
||||
|
||||
o->type = alloc_type_pointer(o->type);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user