diff --git a/src/build/common_build.c b/src/build/common_build.c index aac942a80..c39e9b7df 100644 --- a/src/build/common_build.c +++ b/src/build/common_build.c @@ -119,6 +119,7 @@ const char *get_cflags(BuildParseContext context, JSONObject *json, const char * if (cflags && cflags_add) { // TODO remove in 0.7 + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); error_exit("In file '%s': '%s' is combining both 'cflags-add' and 'cflags-override', only one may be used.", context.file, context.target); } @@ -149,6 +150,7 @@ void get_list_append_strings(BuildParseContext context, JSONObject *json, const if (value && add_value) { // TODO remove in 0.7 + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); error_exit("In file '%s': '%s' is combining both '%s' and '%s', only one may be used.", context.file, context.target, override, add); } if (value) *list_ptr = value; diff --git a/src/compiler/compiler_internal.h b/src/compiler/compiler_internal.h index c5c8519ce..a7bf48ef9 100644 --- a/src/compiler/compiler_internal.h +++ b/src/compiler/compiler_internal.h @@ -2321,7 +2321,7 @@ bool sema_analyse_inferred_expr(SemaContext *context, Type *to, Expr *expr); bool sema_analyse_decl(SemaContext *context, Decl *decl); bool sema_analyse_method_register(SemaContext *context, Decl *method); -bool sema_resolve_type_structure(SemaContext *context, Type *type, SourceSpan span); +bool sema_resolve_type_structure(SemaContext *context, Type *type); bool sema_analyse_var_decl_ct(SemaContext *context, Decl *decl); bool sema_analyse_var_decl(SemaContext *context, Decl *decl, bool local); bool sema_analyse_ct_assert_stmt(SemaContext *context, Ast *statement); diff --git a/src/compiler/parse_expr.c b/src/compiler/parse_expr.c index fa0f1dd48..cb422e384 100644 --- a/src/compiler/parse_expr.c +++ b/src/compiler/parse_expr.c @@ -424,7 +424,6 @@ static Expr *parse_lambda(ParseContext *c, Expr *left) ASSIGN_TYPE_OR_RET(return_type, parse_optional_type(c), poisoned_expr); } CONSUME_OR_RET(TOKEN_LPAREN, poisoned_expr); - Decl **params = NULL; Decl **decls = NULL; Variadic variadic = VARIADIC_NONE; int vararg_index = -1; @@ -454,6 +453,8 @@ static Expr *parse_lambda(ParseContext *c, Expr *left) return expr; } +static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); + /** * vasplat ::= CT_VASPLAT '(' range_expr ')' * -> TODO, this is the only one in 0.7 @@ -471,16 +472,19 @@ Expr *parse_vasplat(ParseContext *c) CONSUME_OR_RET(lparen ? TOKEN_RPAREN : TOKEN_RBRACKET, poisoned_expr); } RANGE_EXTEND_PREV(expr); -END: +END:; // TODO remove in 0.7 + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); if (lparen) { if (expr->vasplat_expr.end || expr->vasplat_expr.start) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "'$vasplat(...)' is deprecated, use '$vasplat[...]' instead."); } else { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "'$vasplat()' is deprecated, use '$vasplat' instead."); } } @@ -494,11 +498,9 @@ END: bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool vasplat) { *result = NULL; - bool has_splat = false; while (1) { Expr *expr = NULL; - DesignatorElement **path; SourceSpan start_span = c->span; if (peek(c) == TOKEN_COLON && token_is_param_name(c->tok)) @@ -524,6 +526,7 @@ bool parse_arg_list(ParseContext *c, Expr ***result, TokenType param_end, bool v CONSUME_OR_RET(TOKEN_EQ, false); ASSIGN_EXPR_OR_RET(expr->named_argument_expr.value, parse_expr(c), false); RANGE_EXTEND_PREV(expr); + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "Named arguments using the '.foo = expr' style are deprecated, please use 'foo: expr' instead."); goto DONE; } @@ -587,7 +590,7 @@ bool parse_init_list(ParseContext *c, Expr ***result, TokenType param_end, bool *splat = try_consume(c, TOKEN_ELLIPSIS); } ASSIGN_EXPR_OR_RET(expr, parse_expr(c), false); - DONE: + DONE: vec_add(*result, expr); if (!try_consume(c, TOKEN_COMMA)) { @@ -654,8 +657,11 @@ Expr *parse_ct_expression_list(ParseContext *c, bool allow_decl) } /** + * type_expr ::= void | any | int | short ... etc + * + * @param c the context * @param left must be null. - * @return Expr* + * @return Expr * */ static Expr *parse_type_identifier(ParseContext *c, Expr *left) { @@ -663,6 +669,13 @@ static Expr *parse_type_identifier(ParseContext *c, Expr *left) return parse_type_expression_with_path(c, NULL); } +/** + * splat_expr ::= '...' expr + * + * @param c the context + * @param left must be null. + * @return Expr * + */ static Expr *parse_splat(ParseContext *c, Expr *left) { ASSERT(!left && "Unexpected left hand side"); @@ -696,6 +709,13 @@ static Expr *parse_type_expr(ParseContext *c, Expr *left) return expr; } +/** + * ct_stringify ::= $stringify '(' expr ')' + * + * @param c the context + * @param left must be null + * @return Expr * + */ static Expr *parse_ct_stringify(ParseContext *c, Expr *left) { ASSERT(!left && "Unexpected left hand side"); @@ -713,15 +733,7 @@ static Expr *parse_ct_stringify(ParseContext *c, Expr *left) RANGE_EXTEND_PREV(expr); return expr; } - size_t len = end - start; - const char *content = str_copy(start, len); - Expr *expr = expr_new(EXPR_CONST, start_span); - expr->const_expr.const_kind = CONST_STRING; - expr->const_expr.bytes.ptr = content; - expr->const_expr.bytes.len = len; - expr->type = type_string; - expr->resolve_status = RESOLVE_DONE; - return expr; + return expr_new_const_string(start_span, str_copy(start, end - start)); } /** @@ -872,8 +884,6 @@ static Expr *parse_grouping_expr(ParseContext *c, Expr *left) * | initializer_values ',' initializer * ; * - * @param elements - * @return */ Expr *parse_initializer_list(ParseContext *c, Expr *left) { @@ -1247,6 +1257,7 @@ static Expr *parse_ct_concat_append(ParseContext *c, Expr *left) { ASSERT(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(tok_is(c, TOKEN_CT_CONCATFN) ? EXPR_CT_CONCAT : EXPR_CT_APPEND); + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "'%s' is deprecated in favour of '+++'.", symstr(c)); advance(c); @@ -1283,6 +1294,7 @@ static Expr *parse_ct_and_or(ParseContext *c, Expr *left) ASSERT(!left && "Unexpected left hand side"); Expr *expr = EXPR_NEW_TOKEN(EXPR_CT_AND_OR); expr->ct_and_or_expr.is_and = tok_is(c, TOKEN_CT_ANDFN); + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "The use of '%s' is deprecated in favour of '%s'.", symstr(c), expr->ct_and_or_expr.is_and ? "&&&" : "|||"); advance(c); @@ -1320,6 +1332,7 @@ static Expr *parse_ct_arg(ParseContext *c, Expr *left) if (type != TOKEN_CT_VACOUNT) { // TODO remove in 0.7 + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); bool is_lparen = try_consume(c, TOKEN_LPAREN); if (!is_lparen) CONSUME_OR_RET(TOKEN_LBRACKET, poisoned_expr); ASSIGN_EXPRID_OR_RET(expr->ct_arg_expr.arg, parse_expr(c), poisoned_expr); @@ -1327,6 +1340,7 @@ static Expr *parse_ct_arg(ParseContext *c, Expr *left) // TODO remove in 0.7 if (is_lparen) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "'%s(...)' is deprecated, use '%s[...]' instead.", token_type_to_string(type), token_type_to_string(type)); } @@ -1359,7 +1373,6 @@ static Expr *parse_identifier(ParseContext *c, Expr *left) static Expr *parse_identifier_starting_expression(ParseContext *c, Expr *left) { ASSERT(!left && "Unexpected left hand side"); - bool had_error; Path *path; if (!parse_path_prefix(c, &path)) return poisoned_expr; switch (c->tok) @@ -1696,7 +1709,7 @@ static void parse_hex(char *result_pointer, const char *data, const char *end) { int val, val2; while ((val = char_hex_to_nibble(*(data++))) < 0) if (data == end) return; - while ((val2 = char_hex_to_nibble(*(data++))) < 0); + while ((val2 = char_hex_to_nibble(*(data++))) < 0) {} *(data_current++) = (char)((val << 4) | val2); } } @@ -1717,6 +1730,7 @@ static char base64_to_sextet(char c) /** * Parse hex, skipping over invalid characters. * @param result_pointer ref to place to put the data + * @param result_pointer_end the end of the result data * @param data start pointer * @param end end pointer */ @@ -1728,9 +1742,9 @@ static void parse_base64(char *result_pointer, char *result_pointer_end, const c { int val, val2, val3, val4; while ((val = base64_to_sextet(*(data++))) < 0) if (data == end) goto DONE; - while ((val2 = base64_to_sextet(*(data++))) < 0); - while ((val3 = base64_to_sextet(*(data++))) < 0); - while ((val4 = base64_to_sextet(*(data++))) < 0); + while ((val2 = base64_to_sextet(*(data++))) < 0) {} + while ((val3 = base64_to_sextet(*(data++))) < 0) {} + while ((val4 = base64_to_sextet(*(data++))) < 0) {} uint32_t triplet = (uint32_t)((val << 3 * 6) + (val2 << 2 * 6) + (val3 << 6) + val4); if (data_current < result_pointer_end) *(data_current++) = (char)((triplet >> 16) & 0xFF); if (data_current < result_pointer_end) *(data_current++) = (char)((triplet >> 8) & 0xFF); diff --git a/src/compiler/parse_global.c b/src/compiler/parse_global.c index 6f07b56d3..386fea376 100644 --- a/src/compiler/parse_global.c +++ b/src/compiler/parse_global.c @@ -432,6 +432,7 @@ static inline TypeInfo *parse_base_type(ParseContext *c) // TODO remove in 0.7 if (is_lparen) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(type_info, "'$vatype(...)' is deprecated, use '$vatype[...]' instead."); } return type_info; diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index b6ab7ac1d..845944118 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1548,6 +1548,7 @@ static void cast_float_to_int(SemaContext *context, Expr *expr, Type *type) */ static void cast_int_to_enum(SemaContext *context, Expr *expr, Type *type) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "Using casts to convert integers to enums is deprecated in favour of using 'MyEnum.from_ordinal(i)`."); Type *canonical = type_flatten(type); ASSERT(canonical->type_kind == TYPE_ENUM); @@ -1642,6 +1643,7 @@ static void cast_int_to_float(SemaContext *context, Expr *expr, Type *type) static void cast_enum_to_int(SemaContext *context, Expr* expr, Type *to_type) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "Using casts to convert enums to integers is deprecated in favour of using 'the_enum.ordinal`."); sema_expr_convert_enum_to_int(context, expr); cast_int_to_int(context, expr, to_type); diff --git a/src/compiler/sema_decls.c b/src/compiler/sema_decls.c index 8a9ba3e15..7978cd8b4 100755 --- a/src/compiler/sema_decls.c +++ b/src/compiler/sema_decls.c @@ -58,8 +58,7 @@ static inline bool sema_analyse_distinct(SemaContext *context, Decl *decl, bool static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit); -static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, - SourceSpan from); +static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params); static inline bool sema_analyse_enum_param(SemaContext *context, Decl *param); static inline bool sema_analyse_enum(SemaContext *context, Decl *decl, bool *erase_decl); @@ -1224,6 +1223,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, case VARDECL_PARAM_REF: if ((i != 0 || !method_parent) && !is_deprecated) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(param, "Reference macro arguments are deprecated."); } if (type_info && !type_is_pointer(param->type)) @@ -2687,6 +2687,7 @@ static bool sema_analyse_attribute(SemaContext *context, ResolvedAttrData *attr_ } case ATTRIBUTE_ADHOC: SEMA_DEPRECATED(attr, "'@adhoc' is deprecated."); + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); return true; case ATTRIBUTE_ALIGN: if (!expr) @@ -3385,7 +3386,7 @@ static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, default: UNREACHABLE } } - else if (is_wmain) + if (is_wmain) { switch (type) { @@ -3395,15 +3396,12 @@ static inline Decl *sema_create_synthetic_main(SemaContext *context, Decl *decl, default: UNREACHABLE } } - else + switch (type) { - switch (type) - { - case 0 : main_invoker = "@main_to_void_main_args"; goto NEXT; - case 1 : main_invoker = "@main_to_int_main_args"; goto NEXT; - case 2 : main_invoker = "@main_to_err_main_args"; goto NEXT; - default: UNREACHABLE - } + case 0: main_invoker = "@main_to_void_main_args"; goto NEXT; + case 1: main_invoker = "@main_to_int_main_args"; goto NEXT; + case 2: main_invoker = "@main_to_err_main_args"; goto NEXT; + default: UNREACHABLE } case MAIN_TYPE_NO_ARGS: ASSERT(!is_wmain); @@ -3487,6 +3485,7 @@ static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl) } is_int_return = false; is_err_return = true; + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(rtype_info, "Main functions with 'void!' returns is deprecated, use 'int' or 'void' instead."); } @@ -3534,10 +3533,7 @@ REGISTER_MAIN: SEMA_NOTE(compiler.context.main, "The first one was found here."); return false; } - else - { - compiler.context.main = function; - } + compiler.context.main = function; return true; } @@ -4258,8 +4254,7 @@ static CompilationUnit *unit_copy(Module *module, CompilationUnit *unit) return copy; } -static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params, - SourceSpan from) +static Module *module_instantiate_generic(SemaContext *context, Module *module, Path *path, Expr **params) { unsigned decls = 0; Decl* params_decls[MAX_PARAMS]; @@ -4271,11 +4266,7 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, Expr *param = params[i]; if (param->expr_kind != EXPR_TYPEINFO) { - if (!is_value) - { - SEMA_ERROR(param, "Expected a type, not a value."); - return NULL; - } + if (!is_value) RETURN_NULL_SEMA_ERROR(param, "Expected a type, not a value."); Decl *decl = decl_new_var(param_name, param->span, NULL, VARDECL_CONST); decl->var.init_expr = param; decl->type = param->type; @@ -4283,13 +4274,9 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module, params_decls[decls++] = decl; continue; } - if (is_value) - { - SEMA_ERROR(param, "Expected a value, not a type."); - return NULL; - } + if (is_value) RETURN_NULL_SEMA_ERROR(param, "Expected a value, not a type."); TypeInfo *type_info = param->type_expr; - if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return false; + if (!sema_resolve_type_info(context, type_info, RESOLVE_TYPE_DEFAULT)) return NULL; Decl *decl = decl_new_with_type(param_name, params[i]->span, DECL_TYPEDEF); decl->resolve_status = RESOLVE_DONE; ASSERT(type_info->resolve_status == RESOLVE_DONE); @@ -4529,9 +4516,9 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con path->module = path_string; path->span = module->name->span; path->len = scratch_buffer.len; - instantiated_module = module_instantiate_generic(c, module, path, params, span); - if (!sema_generate_parameterized_name_to_scratch(c, module, params, false, NULL)) return poisoned_decl; + instantiated_module = module_instantiate_generic(c, module, path, params); if (!instantiated_module) return poisoned_decl; + if (!sema_generate_parameterized_name_to_scratch(c, module, params, false, NULL)) return poisoned_decl; instantiated_module->generic_suffix = scratch_buffer_copy(); sema_analyze_stage(instantiated_module, stage > ANALYSIS_POST_REGISTER ? ANALYSIS_POST_REGISTER : stage); } @@ -4641,7 +4628,7 @@ static inline bool sema_analyse_define(SemaContext *context, Decl *decl, bool *e return true; } -bool sema_resolve_type_structure(SemaContext *context, Type *type, SourceSpan span) +bool sema_resolve_type_structure(SemaContext *context, Type *type) { RETRY: switch (type->type_kind) diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 7588fd84b..2abf095f8 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -6262,6 +6262,7 @@ static bool sema_expr_analyse_enum_add_sub(SemaContext *context, Expr *expr, Exp // Enum - Enum / Enum + Enum if (right_type->type_kind == TYPE_ENUM) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); if (!is_sub) SEMA_DEPRECATED(expr, "Adding two enums is deprecated."); if (left_type != right_type) { @@ -9443,6 +9444,7 @@ static inline bool sema_expr_analyse_ct_arg(SemaContext *context, Type *infer_ty } case TOKEN_CT_VAREF: { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(expr, "'$varef' is deprecated together with '&' arguments."); // A normal argument, this means we only evaluate it once. unsigned index = 0; @@ -9715,7 +9717,7 @@ static inline bool sema_expr_analyse_compound_literal(SemaContext *context, Expr { RETURN_SEMA_ERROR(type_info, "The type here should always be written as a plain type and not an optional, please remove the '!'."); } - if (!sema_resolve_type_structure(context, type, type_info->span)) return false; + if (!sema_resolve_type_structure(context, type)) return false; if (!sema_expr_analyse_initializer_list(context, type, expr->expr_compound_literal.initializer)) return false; expr_replace(expr, expr->expr_compound_literal.initializer); return true; diff --git a/src/compiler/sema_initializers.c b/src/compiler/sema_initializers.c index 9bf4495da..69ae82f5e 100644 --- a/src/compiler/sema_initializers.c +++ b/src/compiler/sema_initializers.c @@ -352,7 +352,7 @@ static inline bool sema_expr_analyse_array_plain_initializer(SemaContext *contex bool is_vector = type_flat_is_vector(assigned); bool inner_is_inferred = type_len_is_inferred(inner_type); Type *inferred_element = NULL; - if (!sema_resolve_type_structure(context, inner_type, initializer->span)) return false; + if (!sema_resolve_type_structure(context, inner_type)) return false; for (unsigned i = 0; i < count; i++) { Expr *element = elements[i]; @@ -528,7 +528,6 @@ static bool sema_expr_analyse_designated_initializer(SemaContext *context, Type if (!inner_type) { inner_type = type_no_optional(value->type); - continue; } } if (bitmember_count_without_value != 0 && bitmember_count_without_value != vec_size(init_expressions)) { @@ -787,7 +786,7 @@ bool sema_expr_analyse_initializer_list(SemaContext *context, Type *to, Expr *ex bool is_zero_init = (expr->expr_kind == EXPR_INITIALIZER_LIST && !vec_size(expr->initializer_list)) || (expr->resolve_status == RESOLVE_DONE && sema_initializer_list_is_empty(expr)); - if (!sema_resolve_type_structure(context, to, expr->span)) return false; + if (!sema_resolve_type_structure(context, to)) return false; switch (flattened->type_kind) { case TYPE_ANY: diff --git a/src/compiler/sema_internal.h b/src/compiler/sema_internal.h index fdeaadb0a..0dd436990 100644 --- a/src/compiler/sema_internal.h +++ b/src/compiler/sema_internal.h @@ -20,6 +20,7 @@ #define SEMA_WARN(_node, ...) (sema_warn_at(context, (_node)->span, __VA_ARGS__)) #define SEMA_ERROR(_node, ...) sema_error_at(context, (_node)->span, __VA_ARGS__) #define RETURN_SEMA_ERROR(_node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return false; } while (0) +#define RETURN_NULL_SEMA_ERROR(_node, ...) do { sema_error_at(context, (_node)->span, __VA_ARGS__); return NULL; } while (0) #define RETURN_SEMA_ERROR_AT(span__, ...) do { sema_error_at(context, span__, __VA_ARGS__); return false; } while (0) #define SCOPE_OUTER_START do { DynamicScope stored_scope = context->active_scope; context_change_scope_with_flags(context, SCOPE_NONE); #define SCOPE_OUTER_END ASSERT(context->active_scope.defer_last == context->active_scope.defer_start); context->active_scope = stored_scope; } while(0) diff --git a/src/compiler/sema_name_resolution.c b/src/compiler/sema_name_resolution.c index c42d2935a..74037b813 100644 --- a/src/compiler/sema_name_resolution.c +++ b/src/compiler/sema_name_resolution.c @@ -150,9 +150,10 @@ static bool sema_find_decl_in_imports(SemaContext *context, NameResolve *name_re // Is the decl in the import. Decl *found = sema_find_decl_in_module(import->import.module, path, symbol, &name_resolve->path_found); + if (!decl_ok(found)) return false; + // No match, so continue if (!found) continue; - ASSERT(found->visibility != VISIBLE_LOCAL); if (found->visibility != VISIBLE_PUBLIC) @@ -403,8 +404,8 @@ static bool sema_find_decl_in_global(SemaContext *context, DeclTable *table, Mod static bool sema_resolve_path_symbol(SemaContext *context, NameResolve *name_resolve) { Path *path = name_resolve->path; + ASSERT(path); name_resolve->ambiguous_other_decl = NULL; - Decl *decl = NULL; name_resolve->path_found = NULL; name_resolve->found = NULL; ASSERT(name_resolve->path && "Expected path."); @@ -588,7 +589,6 @@ static int module_closest_ident_names(Module *module, const char *name, Decl* ma { matches[0] = matches[1] = matches[2] = NULL; - Decl *best = NULL; int count = 0; int len = strlen(name); int distance = MAX(1, (int)(len * 0.8)); @@ -615,11 +615,10 @@ static void sema_report_error_on_decl(SemaContext *context, NameResolve *name_re sema_error_at(context, span, "The %s '%s::%s' is '@private' and not visible from other modules.", private_name, path_name, symbol); - } else - { - sema_error_at(context, span, "The %s '%s' is '@private' and not visible from other modules.", - private_name, symbol); + return; } + sema_error_at(context, span, "The %s '%s' is '@private' and not visible from other modules.", + private_name, symbol); return; } if (!found && name_resolve->maybe_decl) @@ -637,12 +636,10 @@ static void sema_report_error_on_decl(SemaContext *context, NameResolve *name_re { sema_error_at(context, span, "Did you mean the %s '%s::%s' in module %s? If so please add 'import %s'.", maybe_name, module_name, symbol, module_name, module_name); - - } else - { - sema_error_at(context, span, "Did you mean the %s '%s' in module %s? If so please add 'import %s'.", - maybe_name, symbol, module_name, module_name); + return; } + sema_error_at(context, span, "Did you mean the %s '%s' in module %s? If so please add 'import %s'.", + maybe_name, symbol, module_name, module_name); return; } @@ -812,7 +809,7 @@ Decl *sema_resolve_method_in_module(Module *module, Type *actual_type, const cha *private_found = found; found = NULL; } - ASSERT(!found || found->visibility != VISIBLE_LOCAL); + assert(!found || found->visibility != VISIBLE_LOCAL); if (found && search_type == METHOD_SEARCH_CURRENT) return found; // We are now searching submodules, so hide the private ones. if (search_type == METHOD_SEARCH_CURRENT) search_type = METHOD_SEARCH_SUBMODULE_CURRENT; @@ -851,7 +848,7 @@ Decl *sema_resolve_method(CompilationUnit *unit, Decl *type, const char *method_ return sema_resolve_type_method(unit, type->type, method_name, ambiguous_ref, private_ref); } -UNUSED bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info) +bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type_info) { if (!type_info_ok(type_info)) return false; Type *type = type_info->type; diff --git a/src/compiler/sema_stmts.c b/src/compiler/sema_stmts.c index 3e492d735..2589450e9 100644 --- a/src/compiler/sema_stmts.c +++ b/src/compiler/sema_stmts.c @@ -1101,7 +1101,8 @@ static inline bool sema_analyse_cond_list(SemaContext *context, Expr *expr, Cond * * @param context the current context * @param expr the conditional to evaluate - * @param cast_to_bool if the result is to be cast to bool after + * @param cond_type the type of conditional unwrap / unwrap_bool / type + * @param result the result passed back to the caller if known at runtime * @return true if it passes analysis. */ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType cond_type, CondResult *result) @@ -1120,8 +1121,7 @@ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType // signal that. if (type_is_void(expr->type)) { - SEMA_ERROR(expr, cast_to_bool ? "Expected a boolean expression." : "Expected an expression resulting in a value."); - return false; + RETURN_SEMA_ERROR(expr, cast_to_bool ? "Expected a boolean expression." : "Expected an expression resulting in a value."); } // 3. We look at the last element (which is guaranteed to exist because diff --git a/src/compiler/sema_types.c b/src/compiler/sema_types.c index 0b0e9fad7..929cf26b6 100644 --- a/src/compiler/sema_types.c +++ b/src/compiler/sema_types.c @@ -1,4 +1,4 @@ -// Copyright (c) 2020 Christoffer Lerno. All rights reserved. +// Copyright (c) 2020-2025 Christoffer Lerno. All rights reserved. // Use of this source code is governed by a LGPLv3.0 // a copy of which can be found in the LICENSE file. @@ -8,10 +8,12 @@ static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind); static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, ResolveTypeKind resolve_kind); static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind); +static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_type_kind); INLINE bool sema_resolve_vatype(SemaContext *context, TypeInfo *type_info); INLINE bool sema_resolve_evaltype(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind); INLINE bool sema_resolve_typefrom(SemaContext *context, TypeInfo *type_info); INLINE bool sema_resolve_typeof(SemaContext *context, TypeInfo *type_info); +static int compare_function(Signature *sig, FunctionPrototype *proto); static inline bool sema_resolve_ptr_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind) { @@ -94,10 +96,10 @@ bool sema_resolve_array_like_len(SemaContext *context, TypeInfo *type_info, Arra return true; } -static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, ResolveTypeKind resolve_type_kind) +static inline bool sema_resolve_array_type(SemaContext *context, TypeInfo *type, ResolveTypeKind resolve_kind) { // Check the underlying type - if (!sema_resolve_type(context, type->array.base, resolve_type_kind)) return type_info_poison(type); + if (!sema_resolve_type(context, type->array.base, resolve_kind)) return type_info_poison(type); Type *distinct_base = type_flatten(type->array.base->type); @@ -402,6 +404,7 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) if (!context->current_macro && (context->call_env.kind == CALL_ENV_FUNCTION || context->call_env.kind == CALL_ENV_FUNCTION_STATIC) && !context->call_env.current_function->func_decl.in_macro) { + static_assert(ALLOW_DEPRECATED_6, "Fix deprecation"); SEMA_DEPRECATED(type_info, "Nested generic type declarations outside of macros is a deprecated feature, please use 'def' to create an alias."); // TODO, completely disallow // RETURN_SEMA_ERROR(type_info, "Direct generic type declarations are only allowed inside of macros. Use `def` to define an alias for the type instead."); @@ -409,7 +412,7 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info) return true; } -static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_type_kind) +static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, ResolveTypeKind resolve_kind) { // Ok, already resolved. if (type_info->resolve_status == RESOLVE_DONE) @@ -449,10 +452,10 @@ static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, case TYPE_INFO_CT_IDENTIFIER: case TYPE_INFO_IDENTIFIER: // $Type or Foo - if (!sema_resolve_type_identifier(context, type_info, resolve_type_kind)) return type_info_poison(type_info); + if (!sema_resolve_type_identifier(context, type_info, resolve_kind)) return type_info_poison(type_info); goto APPEND_QUALIFIERS; case TYPE_INFO_EVALTYPE: - if (!sema_resolve_evaltype(context, type_info, resolve_type_kind)) return type_info_poison(type_info); + if (!sema_resolve_evaltype(context, type_info, resolve_kind)) return type_info_poison(type_info); goto APPEND_QUALIFIERS; case TYPE_INFO_TYPEOF: if (!sema_resolve_typeof(context, type_info)) return type_info_poison(type_info); @@ -462,8 +465,8 @@ static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, goto APPEND_QUALIFIERS; case TYPE_INFO_INFERRED_VECTOR: case TYPE_INFO_INFERRED_ARRAY: - if (!(resolve_type_kind & RESOLVE_TYPE_ALLOW_INFER) - && (type_info->kind != TYPE_INFO_INFERRED_ARRAY || !(resolve_type_kind & RESOLVE_TYPE_ALLOW_FLEXIBLE))) + if (!(resolve_kind & RESOLVE_TYPE_ALLOW_INFER) + && (type_info->kind != TYPE_INFO_INFERRED_ARRAY || !(resolve_kind & RESOLVE_TYPE_ALLOW_FLEXIBLE))) { SEMA_ERROR(type_info, "Inferred %s types can only be used in declarations with initializers and as macro parameters.", type_info->kind == TYPE_INFO_INFERRED_VECTOR ? "vector" : "array"); @@ -473,13 +476,13 @@ static inline bool sema_resolve_type(SemaContext *context, TypeInfo *type_info, case TYPE_INFO_SLICE: case TYPE_INFO_ARRAY: case TYPE_INFO_VECTOR: - if (!sema_resolve_array_type(context, type_info, resolve_type_kind)) + if (!sema_resolve_array_type(context, type_info, resolve_kind)) { return type_info_poison(type_info); } break; case TYPE_INFO_POINTER: - if (!sema_resolve_ptr_type(context, type_info, resolve_type_kind)) return type_info_poison(type_info); + if (!sema_resolve_ptr_type(context, type_info, resolve_kind)) return type_info_poison(type_info); break; } APPEND_QUALIFIERS: @@ -734,15 +737,13 @@ static int compare_function(Signature *sig, FunctionPrototype *proto) Type *sema_resolve_type_get_func(Signature *signature, CallABI abi) { - uint32_t hash; - hash = hash_function(signature); + uint32_t hash = hash_function(signature); uint32_t mask = map.capacity - 1; uint32_t index = hash & mask; FuncTypeEntry *entries = map.entries; - FuncTypeEntry *entry; while (1) { - entry = &entries[index]; + FuncTypeEntry *entry = &entries[index]; if (!entry->key) { return func_create_new_func_proto(signature, abi, hash, entry); diff --git a/src/compiler/semantic_analyser.c b/src/compiler/semantic_analyser.c index a6a98d57e..d9cfcf459 100644 --- a/src/compiler/semantic_analyser.c +++ b/src/compiler/semantic_analyser.c @@ -320,7 +320,6 @@ static void assign_panicfn(void) const char *panicfn = compiler.build.panicfn ? compiler.build.panicfn : "std::core::builtin::panic"; Path *path; const char *ident; - TokenType type; if (sema_splitpathref(panicfn, strlen(panicfn), &path, &ident) != TOKEN_IDENT || path == NULL || !ident) { error_exit("'%s' is not a valid panic function.", panicfn); @@ -377,12 +376,10 @@ static void assign_testfn(void) if (!compiler.build.testfn && no_stdlib()) { error_exit("No test function could be found."); - return; } const char *testfn = compiler.build.testfn ? compiler.build.testfn : "std::core::runtime::default_test_runner"; Path *path; const char *ident; - TokenType type; if (sema_splitpathref(testfn, strlen(testfn), &path, &ident) != TOKEN_IDENT || path == NULL || !ident) { error_exit("'%s' is not a valid test function.", testfn); @@ -419,7 +416,6 @@ static void assign_benchfn(void) const char *testfn = compiler.build.benchfn ? compiler.build.benchfn : "std::core::runtime::default_benchmark_runner"; Path *path; const char *ident; - TokenType type; if (sema_splitpathref(testfn, strlen(testfn), &path, &ident) != TOKEN_IDENT || path == NULL || !ident) { error_exit("'%s' is not a valid benchmark function.", testfn); diff --git a/src/version.h b/src/version.h index 3debf3987..64f927d41 100644 --- a/src/version.h +++ b/src/version.h @@ -1,2 +1,3 @@ #define COMPILER_VERSION "0.6.7" -#define PRERELEASE 1 \ No newline at end of file +#define PRERELEASE 1 +#define ALLOW_DEPRECATED_6 1 \ No newline at end of file