mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Compiler allows a generic module to be declared with different parameters #1856.
This commit is contained in:
@@ -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.
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
21
test/test_suite/generic/different_generic_def.c3
Normal file
21
test/test_suite/generic/different_generic_def.c3
Normal 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;
|
||||
}
|
||||
Reference in New Issue
Block a user