Browse Source

Fix overriding procedure information for literals

gingerBill 2 years ago
parent
commit
8a2a70a3c2
7 changed files with 33 additions and 11 deletions
  1. 17 0
      src/check_decl.cpp
  2. 3 1
      src/check_expr.cpp
  3. 8 4
      src/check_type.cpp
  4. 2 2
      src/checker.cpp
  5. 2 2
      src/checker.hpp
  6. 0 1
      src/llvm_backend_const.cpp
  7. 1 1
      src/llvm_backend_expr.cpp

+ 17 - 0
src/check_decl.cpp

@@ -1480,6 +1480,23 @@ gb_internal bool check_proc_body(CheckerContext *ctx_, Token token, DeclInfo *de
 	ctx->curr_proc_sig  = type;
 	ctx->curr_proc_calling_convention = type->Proc.calling_convention;
 
+	if (ctx->proc_name == "sort") {
+		if (type->Proc.param_count > 0) {
+			TypeTuple *params = &type->Proc.params->Tuple;
+			for (Entity *e : params->variables) {
+				if (e->kind == Entity_Constant) {
+					Ast *ident = e->identifier.load();
+					if (ident) {
+						add_entity(ctx, e->scope, ident, e);
+						ident->tav.mode = Addressing_Constant;
+						ident->tav.value = e->Constant.value;
+						ident->tav.type = e->type;
+					}
+				}
+			}
+		}
+	}
+
 	if (ctx->pkg->name != "runtime") {
 		switch (type->Proc.calling_convention) {
 		case ProcCC_None:

+ 3 - 1
src/check_expr.cpp

@@ -5418,7 +5418,9 @@ gb_internal CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
 		data->score = score;
 		data->result_type = final_proc_type->Proc.results;
 		data->gen_entity = gen_entity;
-		add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {});
+		if (!are_types_identical(final_proc_type, ce->proc->tav.type)) {
+			add_type_and_value(c, ce->proc, Addressing_Value, final_proc_type, {});
+		}
 	}
 
 	return err;

+ 8 - 4
src/check_type.cpp

@@ -1666,17 +1666,21 @@ gb_internal Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_para
 					if (is_poly_name) {
 						bool valid = false;
 						if (is_type_proc(op.type)) {
-							Entity *proc_entity = entity_from_expr(op.expr);
-							valid = (proc_entity != nullptr) && (op.value.kind == ExactValue_Procedure);
-							if (valid) {
+							Ast *expr = unparen_expr(op.expr);
+							Entity *proc_entity = entity_from_expr(expr);
+							if (proc_entity) {
 								poly_const = exact_value_procedure(proc_entity->identifier.load() ? proc_entity->identifier.load() : op.expr);
+								valid = true;
+							} else if (expr->kind == Ast_ProcLit) {
+								poly_const = exact_value_procedure(expr);
+								valid = true;
 							}
 						}
 						if (!valid) {
 							if (op.mode == Addressing_Constant) {
 								poly_const = op.value;
 							} else {
-								error(op.expr, "Expected a constant value for this polymorphic name parameter");
+								error(op.expr, "Expected a constant value for this polymorphic name parameter, got %s", expr_to_string(op.expr));
 								success = false;
 							}
 						}

+ 2 - 2
src/checker.cpp

@@ -1416,7 +1416,7 @@ gb_internal isize type_info_index(CheckerInfo *info, Type *type, bool error_on_f
 }
 
 
-gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue value) {
+gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
 	if (expr == nullptr) {
 		return;
 	}
@@ -1433,7 +1433,7 @@ gb_internal void add_untyped(CheckerContext *c, Ast *expr, AddressingMode mode,
 	check_set_expr_info(c, expr, mode, type, value);
 }
 
-gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue value) {
+gb_internal void add_type_and_value(CheckerContext *ctx, Ast *expr, AddressingMode mode, Type *type, ExactValue const &value) {
 	if (expr == nullptr) {
 		return;
 	}

+ 2 - 2
src/checker.hpp

@@ -485,9 +485,9 @@ gb_internal void    scope_lookup_parent (Scope *s, String const &name, Scope **s
 gb_internal Entity *scope_insert (Scope *s, Entity *entity);
 
 
-gb_internal void      add_type_and_value      (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue value);
+gb_internal void      add_type_and_value      (CheckerContext *c, Ast *expression, AddressingMode mode, Type *type, ExactValue const &value);
 gb_internal ExprInfo *check_get_expr_info     (CheckerContext *c, Ast *expr);
-gb_internal void      add_untyped             (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue value);
+gb_internal void      add_untyped             (CheckerContext *c, Ast *expression, AddressingMode mode, Type *basic_type, ExactValue const &value);
 gb_internal void      add_entity_use          (CheckerContext *c, Ast *identifier, Entity *entity);
 gb_internal void      add_implicit_entity     (CheckerContext *c, Ast *node, Entity *e);
 gb_internal void      add_entity_and_decl_info(CheckerContext *c, Ast *identifier, Entity *e, DeclInfo *d, bool is_exported=true);

+ 0 - 1
src/llvm_backend_const.cpp

@@ -411,7 +411,6 @@ gb_internal lbValue lb_const_value(lbModule *m, Type *type, ExactValue value, bo
 		Ast *expr = unparen_expr(value.value_procedure);
 		if (expr->kind == Ast_ProcLit) {
 			res = lb_generate_anonymous_proc_lit(m, str_lit("_proclit"), expr);
-
 		} else {
 			Entity *e = entity_from_expr(expr);
 			res = lb_find_procedure_value_from_entity(m, e);

+ 1 - 1
src/llvm_backend_expr.cpp

@@ -3138,7 +3138,7 @@ gb_internal lbValue lb_build_expr_internal(lbProcedure *p, Ast *expr) {
 		Entity *e = entity_from_expr(expr);
 		e = strip_entity_wrapping(e);
 
-		GB_ASSERT_MSG(e != nullptr, "%s", expr_to_string(expr));
+		GB_ASSERT_MSG(e != nullptr, "%s in %.*s %p", expr_to_string(expr), LIT(p->name), expr);
 		if (e->kind == Entity_Builtin) {
 			Token token = ast_token(expr);
 			GB_PANIC("TODO(bill): lb_build_expr Entity_Builtin '%.*s'\n"