diff --git a/src/check_decl.cpp b/src/check_decl.cpp index 1a6fad918..f3e0f70bc 100644 --- a/src/check_decl.cpp +++ b/src/check_decl.cpp @@ -1141,7 +1141,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty } ast_node(bs, BlockStmt, body); - // check_open_scope(ctx, body); + check_open_scope(ctx, body); check_stmt_list(ctx, bs->stmts, Stmt_CheckScopeDecls); if (type->Proc.result_count > 0) { if (!check_is_terminating(body)) { @@ -1153,7 +1153,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty } } } - // check_close_scope(ctx); + check_close_scope(ctx); check_scope_usage(ctx->checker, ctx->scope); diff --git a/src/checker.cpp b/src/checker.cpp index 9abd8c499..f68e2ab15 100644 --- a/src/checker.cpp +++ b/src/checker.cpp @@ -400,6 +400,15 @@ Entity *scope_insert_with_name(Scope *s, String name, Entity *entity) { if (found) { return *found; } + if (s->parent != nullptr && (s->parent->flags & ScopeFlag_Proc) != 0) { + Entity **found = map_get(&s->parent->elements, key); + if (found) { + if ((*found)->flags & EntityFlag_Result) { + return *found; + } + } + } + map_set(&s->elements, key, entity); if (entity->scope == nullptr) { entity->scope = s; @@ -1044,21 +1053,37 @@ bool redeclaration_error(String name, Entity *prev, Entity *found) { // NOTE(bill): Error should have been handled already return false; } - error(prev->token, - "Redeclaration of '%.*s' in this scope through 'using'\n" - "\tat %.*s(%td:%td)", - LIT(name), - LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column); + if (found->flags & EntityFlag_Result) { + error(prev->token, + "Direct shadowing of the named return value '%.*s' in this scope through 'using'\n" + "\tat %.*s(%td:%td)", + LIT(name), + LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column); + } else { + error(prev->token, + "Redeclaration of '%.*s' in this scope through 'using'\n" + "\tat %.*s(%td:%td)", + LIT(name), + LIT(up->token.pos.file), up->token.pos.line, up->token.pos.column); + } } else { if (pos == prev->token.pos) { // NOTE(bill): Error should have been handled already return false; } - error(prev->token, - "Redeclaration of '%.*s' in this scope\n" - "\tat %.*s(%td:%td)", - LIT(name), - LIT(pos.file), pos.line, pos.column); + if (found->flags & EntityFlag_Result) { + error(prev->token, + "Direct shadowing of the named return value '%.*s' in this scope\n" + "\tat %.*s(%td:%td)", + LIT(name), + LIT(pos.file), pos.line, pos.column); + } else { + error(prev->token, + "Redeclaration of '%.*s' in this scope\n" + "\tat %.*s(%td:%td)", + LIT(name), + LIT(pos.file), pos.line, pos.column); + } } return false; }