mirror of
https://github.com/odin-lang/Odin.git
synced 2026-02-12 06:18:39 +00:00
Require all values from a procedure iterator if the procedure is marked with @(require_results)
This commit is contained in:
@@ -1724,6 +1724,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
bool is_range = false;
|
||||
bool is_possibly_addressable = true;
|
||||
isize max_val_count = 2;
|
||||
|
||||
if (is_ast_range(expr)) {
|
||||
ast_node(ie, BinaryExpr, expr);
|
||||
Operand x = {};
|
||||
@@ -1884,7 +1885,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
error_line("\tMultiple return valued parameters in a range statement are limited to a minimum of 1 usable values with a trailing boolean for the conditional, got %td\n", count);
|
||||
break;
|
||||
}
|
||||
enum : isize {MAXIMUM_COUNT = 100};
|
||||
enum : isize {MAXIMUM_COUNT = 20};
|
||||
if (count > MAXIMUM_COUNT) {
|
||||
ERROR_BLOCK();
|
||||
check_not_tuple(ctx, &operand);
|
||||
@@ -1900,7 +1901,7 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
break;
|
||||
}
|
||||
|
||||
max_val_count = count;
|
||||
max_val_count = count-1;
|
||||
|
||||
for (Entity *e : t->Tuple.variables) {
|
||||
array_add(&vals, e->type);
|
||||
@@ -1920,6 +1921,20 @@ gb_internal void check_range_stmt(CheckerContext *ctx, Ast *node, u32 mod_flags)
|
||||
if (is_reverse) {
|
||||
error(node, "#reverse for is not supported for multiple return valued parameters");
|
||||
}
|
||||
|
||||
Ast *expr = unparen_expr(operand.expr);
|
||||
if (expr->kind == Ast_CallExpr) {
|
||||
Type *p = base_type(type_of_expr(expr->CallExpr.proc));
|
||||
if (p != nullptr && p->kind == Type_Proc) {
|
||||
if (p->Proc.require_results) {
|
||||
if (rs->vals.count < max_val_count) {
|
||||
TokenPos start = ast_token(rs->vals[0]).pos;
|
||||
TokenPos end = ast_end_pos(rs->vals[rs->vals.count-1]);
|
||||
error_range(start, end, "Expected a %td identifier%s, got %td", max_val_count, max_val_count == 1 ? "" : "s", rs->vals.count);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
|
||||
@@ -514,6 +514,22 @@ gb_internal void error(Ast *node, char const *fmt, ...) {
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void error_range(TokenPos start, TokenPos end, char const *fmt, ...) {
|
||||
GB_ASSERT(start.file_id == end.file_id);
|
||||
GB_ASSERT(start.line == end.line);
|
||||
GB_ASSERT(start.column <= end.column);
|
||||
GB_ASSERT(start.offset <= end.offset);
|
||||
|
||||
va_list va;
|
||||
va_start(va, fmt);
|
||||
error_va(start, end, fmt, va);
|
||||
va_end(va);
|
||||
if (start.file_id != 0) {
|
||||
AstFile *f = thread_safe_get_ast_file_from_id(start.file_id);
|
||||
f->error_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
gb_internal void syntax_error_with_verbose(Ast *node, char const *fmt, ...) {
|
||||
Token token = {};
|
||||
TokenPos end_pos = {};
|
||||
|
||||
Reference in New Issue
Block a user