aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorgingerBill <bill@gingerbill.org>2020-05-13 23:45:55 +0100
committergingerBill <bill@gingerbill.org>2020-05-13 23:45:55 +0100
commitc2bfb221f551c081ff0f2114a2a28a3d50dc3e6d (patch)
tree77d54e28b6f46571d7d6f6688ca60a8a1bd987b5 /src
parentd59fced21b0c94a4a41f0213f62120dbe0f9b710 (diff)
Fix #561 `where` statements that eval to false do not show incorrect usage location
Diffstat (limited to 'src')
-rw-r--r--src/check_decl.cpp2
-rw-r--r--src/check_expr.cpp32
-rw-r--r--src/checker.hpp1
3 files changed, 33 insertions, 2 deletions
diff --git a/src/check_decl.cpp b/src/check_decl.cpp
index 69e7c563e..f629a0903 100644
--- a/src/check_decl.cpp
+++ b/src/check_decl.cpp
@@ -1237,7 +1237,7 @@ void check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *decl, Type *ty
}
- bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true);
+ bool where_clause_ok = evaluate_where_clauses(ctx, nullptr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, !decl->where_clauses_evaluated);
if (!where_clause_ok) {
// NOTE(bill, 2019-08-31): Don't check the body as the where clauses failed
return;
diff --git a/src/check_expr.cpp b/src/check_expr.cpp
index 78566a401..f6fbd25c4 100644
--- a/src/check_expr.cpp
+++ b/src/check_expr.cpp
@@ -6766,7 +6766,7 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
ctx.curr_proc_sig = e->type;
GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit);
- if (!evaluate_where_clauses(&ctx, operand->expr, decl->scope, &decl->proc_lit->ProcLit.where_clauses, false)) {
+ if (!evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, false)) {
continue;
}
}
@@ -6921,6 +6921,21 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
add_entity_use(c, ident, entity_to_use);
+ if (data.gen_entity != nullptr) {
+ Entity *e = data.gen_entity;
+ DeclInfo *decl = data.gen_entity->decl_info;
+ CheckerContext ctx = *c;
+ ctx.scope = decl->scope;
+ ctx.decl = decl;
+ ctx.proc_name = e->token.string;
+ ctx.curr_proc_decl = decl;
+ ctx.curr_proc_sig = e->type;
+
+ GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit);
+ evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true);
+ decl->where_clauses_evaluated = true;
+ }
+
return data;
}
} else {
@@ -6937,6 +6952,21 @@ CallArgumentData check_call_arguments(CheckerContext *c, Operand *operand, Type
Entity *entity_to_use = data.gen_entity != nullptr ? data.gen_entity : e;
add_entity_use(c, ident, entity_to_use);
+ if (data.gen_entity != nullptr) {
+ Entity *e = data.gen_entity;
+ DeclInfo *decl = data.gen_entity->decl_info;
+ CheckerContext ctx = *c;
+ ctx.scope = decl->scope;
+ ctx.decl = decl;
+ ctx.proc_name = e->token.string;
+ ctx.curr_proc_decl = decl;
+ ctx.curr_proc_sig = e->type;
+
+ GB_ASSERT(decl->proc_lit->kind == Ast_ProcLit);
+ evaluate_where_clauses(&ctx, call, decl->scope, &decl->proc_lit->ProcLit.where_clauses, true);
+ decl->where_clauses_evaluated = true;
+ }
+
return data;
}
diff --git a/src/checker.hpp b/src/checker.hpp
index 1f03a95d1..5f5486fe2 100644
--- a/src/checker.hpp
+++ b/src/checker.hpp
@@ -137,6 +137,7 @@ struct DeclInfo {
Ast * proc_lit; // Ast_ProcLit
Type * gen_proc_type; // Precalculated
bool is_using;
+ bool where_clauses_evaluated;
PtrSet<Entity *> deps;
PtrSet<Type *> type_info_deps;