Compiler allows a generic module to be declared with different parameters #1856.

This commit is contained in:
Christoffer Lerno
2025-01-17 23:24:42 +01:00
parent 304b604652
commit c5dbbf9ff7
3 changed files with 49 additions and 11 deletions

View File

@@ -9,6 +9,7 @@
- Fix issue requiring prefix on a generic interface declaration.
- Fix bug in SHA1 for longer blocks #1854.
- Fix lack of location for reporting lambdas with missing return statement #1857.
- Compiler allows a generic module to be declared with different parameters #1856.
### Stdlib changes
- Added '%h' and '%H' for printing out binary data in hexadecimal using the formatter.

View File

@@ -20,26 +20,42 @@ static inline bool create_module_or_check_name(CompilationUnit *unit, Path *modu
if (!module)
{
module = unit->module = compiler_find_or_create_module(module_name, parameters);
if ((parameters == NULL) == module->is_generic)
if (module->is_generic != (parameters != NULL))
{
print_error_at(module_name->span, "'%s' is both used as regular and generic module, it can't be both.",
module_name->module);
module_name->module);
SEMA_NOTE(module->name, "The definition here is different.");
return false;
}
}
else
{
if (unit->module->name->module != module_name->module)
if (!module->is_generic) goto DONE;
if (vec_size(parameters) != vec_size(module->parameters))
{
RETURN_PRINT_ERROR_AT(false,
module_name,
"Module name here '%s' did not match actual module '%s'.",
module_name->module,
module->name->module);
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.");
SEMA_NOTE(module->name, "A different definition can be found here.");
return false;
}
FOREACH_IDX(idx, const char *, name, parameters)
{
bool is_type = str_is_type(name);
if (is_type != str_is_type(module->parameters[idx]))
{
PRINT_ERROR_AT(module_name, "The parameter declarations of the generic module '%s' don't match.");
SEMA_NOTE(module->name, "The other definition is here.");
return false;
}
}
goto DONE;
}
if (unit->module->name->module != module_name->module)
{
RETURN_PRINT_ERROR_AT(false,
module_name,
"Module name here '%s' did not match actual module '%s'.",
module_name->module,
module->name->module);
}
DONE:;
vec_add(module->units, unit);
return true;
}

View File

@@ -0,0 +1,21 @@
module test;
import test2;
fn int main()
{
Foo1(<int>) a;
return 0;
}
module test2(<Type>);
struct Foo
{
Type f;
}
module test2(<Type, FOO>); // #error: declarations of the generic
struct Foo1
{
Type a;
}