From b84e7c69ae52155c4902cf24b4f9bb86d65d5f9e Mon Sep 17 00:00:00 2001 From: Bruce Hill Date: Sun, 21 Sep 2025 18:46:28 -0400 Subject: Be more lenient with underscore fields and arguments. --- src/compile/functions.c | 3 ++- src/compile/structs.c | 4 +++- src/typecheck.c | 16 +--------------- 3 files changed, 6 insertions(+), 17 deletions(-) (limited to 'src') diff --git a/src/compile/functions.c b/src/compile/functions.c index abe0a588..e3dbc2e7 100644 --- a/src/compile/functions.c +++ b/src/compile/functions.c @@ -155,7 +155,8 @@ Text_t compile_function_call(env_t *env, ast_t *ast) { if (!is_valid_call(env, Match(fn_t, FunctionType)->args, call->args, (call_opts_t){.promotion = true})) { if (is_valid_call(env, Match(fn_t, FunctionType)->args, call->args, (call_opts_t){.promotion = true, .underscores = true})) { - code_err(ast, "You can't pass underscore arguments to this function (those are private)"); + code_err(ast, "You can't pass underscore arguments to this function as positional arguments. You must " + "use keyword arguments."); } else { arg_t *args = NULL; for (arg_ast_t *a = call->args; a; a = a->next) diff --git a/src/compile/structs.c b/src/compile/structs.c index aaebef22..2e7217f6 100644 --- a/src/compile/structs.c +++ b/src/compile/structs.c @@ -127,7 +127,9 @@ Text_t compile_struct_literal(env_t *env, ast_t *ast, type_t *t, arg_ast_t *args return Texts("((", compile_type(t), "){", compile_arguments(env, ast, struct_->fields, args), "})"); } else if (!constructor_opts.underscores && is_valid_call(env, struct_->fields, args, (call_opts_t){.promotion = true, .underscores = true})) { - code_err(ast, "This constructor uses private fields that are not exposed."); + code_err(ast, "This constructor is passing private fields (those starting with underscores) as positional " + "arguments, which is not allowed. \n" + " If you need to pass these fields, use a keyword argument."); } code_err(ast, "I could not find a constructor matching these arguments for the struct ", type_to_text(t)); } diff --git a/src/typecheck.c b/src/typecheck.c index 9d33e119..6cd87289 100644 --- a/src/typecheck.c +++ b/src/typecheck.c @@ -905,16 +905,6 @@ type_t *get_type(env_t *env, ast_t *ast) { case FieldAccess: { DeclareMatch(access, ast, FieldAccess); type_t *fielded_t = get_type(env, access->fielded); - if (access->field[0] == '_') { - if (!env->current_type - || !type_eq(env->current_type, fielded_t->tag == TypeInfoType ? Match(fielded_t, TypeInfoType)->type - : value_type(fielded_t))) - code_err(ast, "Fields beginning with underscores like '", access->field, - "' can't be accessed outside the scope where the type (", - type_to_text(fielded_t->tag == TypeInfoType ? Match(fielded_t, TypeInfoType)->type - : value_type(fielded_t)), - ") is defined."); - } if (fielded_t->tag == ModuleType) { const char *name = Match(fielded_t, ModuleType)->name; env_t *module_env = Table$str_get(*env->imports, name); @@ -1049,9 +1039,7 @@ type_t *get_type(env_t *env, ast_t *ast) { if (call->name[0] == '_') { if (env->current_type == NULL || !type_eq(env->current_type, self_value_t)) code_err(ast, "You can't call private methods starting with underscore (like '", call->name, - "') " - "outside of the place where the type (", - type_to_text(self_value_t), ") is defined."); + "') outside of the place where the type (", type_to_text(self_value_t), ") is defined."); } type_t *field_type = get_field_type(self_value_t, call->name); if (field_type && field_type->tag == ClosureType) field_type = Match(field_type, ClosureType)->fn; @@ -1625,10 +1613,8 @@ bool is_valid_call(env_t *env, arg_t *spec_args, arg_ast_t *call_args, call_opts // Populate keyword args: for (arg_ast_t *call_arg = call_args; call_arg; call_arg = call_arg->next) { if (!call_arg->name) continue; - if (!options.underscores && call_arg->name[0] == '_') return false; for (arg_t *spec_arg = spec_args; spec_arg; spec_arg = spec_arg->next) { - if (!options.underscores && spec_arg->name[0] == '_') continue; if (!(streq(call_arg->name, spec_arg->name) || (spec_arg->alias && streq(call_arg->name, spec_arg->alias)))) continue; type_t *spec_type = get_arg_type(env, spec_arg); -- cgit v1.2.3