mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Allow recursive generic modules.
This commit is contained in:
@@ -21,6 +21,7 @@
|
||||
- Add `$$matrix_mul` and `$$matrix_transpose` builtins.
|
||||
- Add `d` as floating point suffix for `double` types.
|
||||
- Deprecate `f32`, `f64` and `f128` suffixes.
|
||||
- Allow recursive generic modules.
|
||||
|
||||
### Fixes
|
||||
- Assert triggered when casting from `int[2]` to `uint[2]` #2115
|
||||
|
||||
@@ -2374,6 +2374,14 @@ static inline bool unit_add_method(SemaContext *context, Type *parent_type, Decl
|
||||
other = sema_resolve_method(unit, parent, name, &ambiguous, &private);
|
||||
if (other)
|
||||
{
|
||||
if (unit->module->generic_module && other->unit->module->generic_module == unit->module->generic_module)
|
||||
{
|
||||
const char *module_name = unit->module->generic_module->name->module;
|
||||
RETURN_SEMA_ERROR(method, "The same method is generated by multiple instances of '%s': '%s%s' and '%s%s'. "
|
||||
"You need to use `@if` to restrict it to one of them, or move it out of the generic module entirely.",
|
||||
module_name, module_name, unit->module->generic_suffix, module_name, other->unit->module->generic_suffix);
|
||||
}
|
||||
|
||||
SEMA_ERROR(method, "This %s is already defined for '%s'.",
|
||||
method_name_by_decl(method), parent_type->name);
|
||||
SEMA_NOTE(other, "The previous definition was here.");
|
||||
@@ -4890,12 +4898,6 @@ Decl *sema_analyse_parameterized_identifier(SemaContext *c, Path *decl_path, con
|
||||
ASSERT(alias);
|
||||
Module *module = alias->unit->module;
|
||||
|
||||
if (c->unit->module->generic_module == module)
|
||||
{
|
||||
sema_error_at(c, span, "This identifier is recursively using %s.", module->name->module);
|
||||
return poisoned_decl;
|
||||
}
|
||||
|
||||
unsigned parameter_count = vec_size(module->parameters);
|
||||
ASSERT(parameter_count > 0);
|
||||
if (parameter_count != vec_size(params))
|
||||
|
||||
@@ -246,6 +246,7 @@ static bool sema_resolve_type_identifier(SemaContext *context, TypeInfo *type_in
|
||||
case DECL_TYPEDEF:
|
||||
if (!sema_analyse_decl(context, decl)) return type_info_poison(type_info);
|
||||
type_info->type = decl->type;
|
||||
assert (type_info->type->canonical->type_kind != TYPE_TYPEDEF);
|
||||
type_info->resolve_status = RESOLVE_DONE;
|
||||
return true;
|
||||
case DECL_POISONED:
|
||||
@@ -415,12 +416,13 @@ INLINE bool sema_resolve_generic_type(SemaContext *context, TypeInfo *type_info)
|
||||
Decl *type = sema_analyse_parameterized_identifier(context, inner->unresolved.path, inner->unresolved.name,
|
||||
inner->span, type_info->generic.params, &was_recursive);
|
||||
if (!decl_ok(type)) return false;
|
||||
if (!sema_analyse_decl(context, type)) return false;
|
||||
type_info->type = type->type;
|
||||
if (!was_recursive) return true;
|
||||
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)
|
||||
{
|
||||
RETURN_SEMA_ERROR(type_info, "Recursively generic type declarations are only allowed inside of macros. Use `def` to define an alias for the type instead.");
|
||||
RETURN_SEMA_ERROR(type_info, "Recursively generic type declarations are only allowed inside of macros. Use `alias` to define an alias for the type instead.");
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user