Browse Source

Fix #561 `where` statements that eval to false do not show incorrect usage location

gingerBill 5 năm trước cách đây
mục cha
commit
c2bfb221f5
3 tập tin đã thay đổi với 33 bổ sung2 xóa
  1. 1 1
      src/check_decl.cpp
  2. 31 1
      src/check_expr.cpp
  3. 1 0
      src/checker.hpp

+ 1 - 1
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;

+ 31 - 1
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;
 	}
 

+ 1 - 0
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;