mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Generic modules parameterized with constants would sometimes get the wrong parameterized module name causing conversion errors #1192.
This commit is contained in:
@@ -12,6 +12,7 @@
|
|||||||
### Fixes
|
### Fixes
|
||||||
- Incorrect length passed to scratch buffer printf.
|
- Incorrect length passed to scratch buffer printf.
|
||||||
- Casting to a bitstruct would be allowed even if the type was the wrong size.
|
- Casting to a bitstruct would be allowed even if the type was the wrong size.
|
||||||
|
- Generic modules parameterized with constants would sometimes get the wrong parameterized module name causing conversion errors #1192.
|
||||||
|
|
||||||
### Stdlib changes
|
### Stdlib changes
|
||||||
- Add 'zstr' variants for `string::new_format` / `string::tformat`.
|
- Add 'zstr' variants for `string::new_format` / `string::tformat`.
|
||||||
|
|||||||
@@ -366,6 +366,7 @@ typedef enum
|
|||||||
SCOPE_ENSURE_MACRO = 1 << 2,
|
SCOPE_ENSURE_MACRO = 1 << 2,
|
||||||
SCOPE_EXPR_BLOCK = 1 << 3,
|
SCOPE_EXPR_BLOCK = 1 << 3,
|
||||||
SCOPE_MACRO = 1 << 4,
|
SCOPE_MACRO = 1 << 4,
|
||||||
|
SCOPE_COND = 1 << 5,
|
||||||
} ScopeFlags;
|
} ScopeFlags;
|
||||||
|
|
||||||
typedef enum
|
typedef enum
|
||||||
|
|||||||
@@ -3471,8 +3471,38 @@ static Module *module_instantiate_generic(SemaContext *context, Module *module,
|
|||||||
return new_module;
|
return new_module;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool sema_append_generate_parameterized_name(SemaContext *c, Module *module, Expr **params, bool mangled)
|
static bool sema_generate_parameterized_name_to_scratch(SemaContext *c, Module *module, Expr **params, bool mangled)
|
||||||
{
|
{
|
||||||
|
// First resolve
|
||||||
|
FOREACH_BEGIN_IDX(i, Expr *param, params)
|
||||||
|
if (param->expr_kind == EXPR_TYPEINFO)
|
||||||
|
{
|
||||||
|
TypeInfo *type_info = param->type_expr;
|
||||||
|
if (!sema_resolve_type_info(c, type_info, RESOLVE_TYPE_DEFAULT)) return false;
|
||||||
|
Type *type = type_info->type->canonical;
|
||||||
|
if (type->type_kind == TYPE_OPTIONAL) RETURN_SEMA_ERROR(type_info, "Expected a non-optional type.");
|
||||||
|
if (type_is_void(type)) RETURN_SEMA_ERROR(type_info, "A 'void' type cannot be used as a parameter type.");
|
||||||
|
if (type_is_invalid_storage_type(type)) RETURN_SEMA_ERROR(type_info, "Expected a runtime type.");
|
||||||
|
if (type_is_func_ptr(type))
|
||||||
|
{
|
||||||
|
if (!sema_resolve_type_decl(c, type->pointer)) return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (!sema_analyse_ct_expr(c, param)) return false;
|
||||||
|
Type *type = param->type->canonical;
|
||||||
|
bool is_enum_like = type_kind_is_enumlike(type->type_kind);
|
||||||
|
if (!type_is_integer_or_bool_kind(type) && !is_enum_like)
|
||||||
|
{
|
||||||
|
SEMA_ERROR(param, "Only integer, bool, fault and enum values may be generic arguments.");
|
||||||
|
return poisoned_decl;
|
||||||
|
}
|
||||||
|
assert(expr_is_const(param));
|
||||||
|
}
|
||||||
|
FOREACH_END();
|
||||||
|
|
||||||
|
scratch_buffer_clear();
|
||||||
if (mangled)
|
if (mangled)
|
||||||
{
|
{
|
||||||
scratch_buffer_append_len(module->name->module, module->name->len);
|
scratch_buffer_append_len(module->name->module, module->name->len);
|
||||||
@@ -3489,36 +3519,20 @@ static bool sema_append_generate_parameterized_name(SemaContext *c, Module *modu
|
|||||||
}
|
}
|
||||||
if (param->expr_kind == EXPR_TYPEINFO)
|
if (param->expr_kind == EXPR_TYPEINFO)
|
||||||
{
|
{
|
||||||
TypeInfo *type_info = param->type_expr;
|
Type *type = param->type_expr->type->canonical;
|
||||||
if (!sema_resolve_type_info(c, type_info, RESOLVE_TYPE_DEFAULT)) return false;
|
|
||||||
Type *type = type_info->type->canonical;
|
|
||||||
if (type->type_kind == TYPE_OPTIONAL) RETURN_SEMA_ERROR(type_info, "Expected a non-optional type.");
|
|
||||||
if (type_is_void(type)) RETURN_SEMA_ERROR(type_info, "A 'void' type cannot be used as a parameter type.");
|
|
||||||
if (type_is_invalid_storage_type(type)) RETURN_SEMA_ERROR(type_info, "Expected a runtime type.");
|
|
||||||
if (type_is_func_ptr(type))
|
|
||||||
{
|
|
||||||
if (!sema_resolve_type_decl(c, type->pointer)) return false;
|
|
||||||
}
|
|
||||||
if (mangled)
|
if (mangled)
|
||||||
{
|
{
|
||||||
type_mangle_introspect_name_to_buffer(type);
|
type_mangle_introspect_name_to_buffer(type);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
scratch_buffer_append(type_info->type->name);
|
scratch_buffer_append(type->name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (!sema_analyse_ct_expr(c, param)) return false;
|
|
||||||
Type *type = param->type->canonical;
|
Type *type = param->type->canonical;
|
||||||
bool is_enum_like = type_kind_is_enumlike(type->type_kind);
|
bool is_enum_like = type_kind_is_enumlike(type->type_kind);
|
||||||
if (!type_is_integer_or_bool_kind(type) && !is_enum_like)
|
|
||||||
{
|
|
||||||
SEMA_ERROR(param, "Only integer, bool, fault and enum values may be generic arguments.");
|
|
||||||
return poisoned_decl;
|
|
||||||
}
|
|
||||||
assert(expr_is_const(param));
|
|
||||||
if (type == type_bool)
|
if (type == type_bool)
|
||||||
{
|
{
|
||||||
if (mangled)
|
if (mangled)
|
||||||
@@ -3656,8 +3670,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
|
|||||||
vec_size(params));
|
vec_size(params));
|
||||||
return poisoned_decl;
|
return poisoned_decl;
|
||||||
}
|
}
|
||||||
scratch_buffer_clear();
|
if (!sema_generate_parameterized_name_to_scratch(c, module, params, true)) return poisoned_decl;
|
||||||
if (!sema_append_generate_parameterized_name(c, module, params, true)) return poisoned_decl;
|
|
||||||
TokenType ident_type = TOKEN_IDENT;
|
TokenType ident_type = TOKEN_IDENT;
|
||||||
const char *path_string = scratch_buffer_interned();
|
const char *path_string = scratch_buffer_interned();
|
||||||
Module *instantiated_module = global_context_find_module(path_string);
|
Module *instantiated_module = global_context_find_module(path_string);
|
||||||
@@ -3671,8 +3684,7 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
|
|||||||
path->span = module->name->span;
|
path->span = module->name->span;
|
||||||
path->len = scratch_buffer.len;
|
path->len = scratch_buffer.len;
|
||||||
instantiated_module = module_instantiate_generic(c, module, path, params, span);
|
instantiated_module = module_instantiate_generic(c, module, path, params, span);
|
||||||
scratch_buffer_clear();
|
if (!sema_generate_parameterized_name_to_scratch(c, module, params, false)) return poisoned_decl;
|
||||||
if (!sema_append_generate_parameterized_name(c, module, params, false)) return poisoned_decl;
|
|
||||||
if (!instantiated_module) return poisoned_decl;
|
if (!instantiated_module) return poisoned_decl;
|
||||||
instantiated_module->generic_suffix = scratch_buffer_copy();
|
instantiated_module->generic_suffix = scratch_buffer_copy();
|
||||||
if (c->unit->module->generic_module)
|
if (c->unit->module->generic_module)
|
||||||
|
|||||||
@@ -1025,7 +1025,12 @@ static inline bool sema_analyse_cond(SemaContext *context, Expr *expr, CondType
|
|||||||
assert(expr->expr_kind == EXPR_COND && "Conditional expressions should always be of type EXPR_DECL_LIST");
|
assert(expr->expr_kind == EXPR_COND && "Conditional expressions should always be of type EXPR_DECL_LIST");
|
||||||
|
|
||||||
// 1. Analyse the declaration list.
|
// 1. Analyse the declaration list.
|
||||||
if (!sema_analyse_cond_list(context, expr, cond_type)) return false;
|
ScopeFlags current_flags = context->active_scope.flags;
|
||||||
|
context->active_scope.flags |= SCOPE_COND;
|
||||||
|
bool success = sema_analyse_cond_list(context, expr, cond_type);
|
||||||
|
context->active_scope.flags = current_flags;
|
||||||
|
if (!success) return false;
|
||||||
|
|
||||||
|
|
||||||
// 2. If we get "void", either through a void call or an empty list,
|
// 2. If we get "void", either through a void call or an empty list,
|
||||||
// signal that.
|
// signal that.
|
||||||
|
|||||||
Reference in New Issue
Block a user