mirror of
https://github.com/c3lang/c3c.git
synced 2026-02-27 12:01:16 +00:00
Fix: Compiler assert when attempting to define multiple faults in a generic module. #2706
This commit is contained in:
@@ -327,6 +327,45 @@ bool decl_is_defaulted_var(Decl *decl)
|
||||
return decl->decl_kind == DECL_VAR && decl->var.no_init && decl->var.defaulted;
|
||||
}
|
||||
|
||||
bool decl_may_be_generic(Decl *decl)
|
||||
{
|
||||
switch (decl->decl_kind)
|
||||
{
|
||||
case DECL_POISONED:
|
||||
case DECL_BODYPARAM:
|
||||
case DECL_CT_ASSERT:
|
||||
case DECL_CT_ECHO:
|
||||
case DECL_CT_EXEC:
|
||||
case DECL_CT_INCLUDE:
|
||||
case DECL_ALIAS_PATH:
|
||||
case DECL_ENUM_CONSTANT:
|
||||
case DECL_ERASED:
|
||||
case DECL_FAULT:
|
||||
case DECL_GROUP:
|
||||
case DECL_GENERIC:
|
||||
case DECL_GENERIC_INSTANCE:
|
||||
case DECL_IMPORT:
|
||||
case DECL_LABEL:
|
||||
case DECL_CONST_ENUM:
|
||||
return false;
|
||||
case DECL_ATTRIBUTE:
|
||||
case DECL_BITSTRUCT:
|
||||
case DECL_DECLARRAY:
|
||||
case DECL_ALIAS:
|
||||
case DECL_TYPEDEF:
|
||||
case DECL_ENUM:
|
||||
case DECL_FNTYPE:
|
||||
case DECL_FUNC:
|
||||
case DECL_MACRO:
|
||||
case DECL_INTERFACE:
|
||||
case DECL_STRUCT:
|
||||
case DECL_TYPE_ALIAS:
|
||||
case DECL_UNION:
|
||||
case DECL_VAR:
|
||||
return true;
|
||||
}
|
||||
UNREACHABLE
|
||||
}
|
||||
/*
|
||||
* Count the expected number of elements needed for an initializer
|
||||
* by folding any anonymous structs and unions.
|
||||
|
||||
@@ -2382,6 +2382,7 @@ const char *decl_to_name(Decl *decl);
|
||||
const char *decl_to_a_name(Decl *decl);
|
||||
int decl_count_elements(Decl *structlike);
|
||||
bool decl_is_defaulted_var(Decl *decl);
|
||||
bool decl_may_be_generic(Decl *decl);
|
||||
void decl_append_links_to_global_during_codegen(Decl *decl);
|
||||
Decl *decl_template_get_generic(Decl *decl);
|
||||
|
||||
|
||||
@@ -1323,12 +1323,18 @@ static bool parse_attributes_for_global(ParseContext *c, Decl *decl)
|
||||
bool is_builtin = false;
|
||||
bool is_cond;
|
||||
Decl *generics = NULL;
|
||||
bool can_be_generic = decl_may_be_generic(decl);
|
||||
if (!parse_attributes(c, &decl->attributes, &visibility, decl_needs_prefix(decl) ? &is_builtin : NULL, &is_cond, &generics)) return false;
|
||||
if (generics)
|
||||
{
|
||||
if (!can_be_generic)
|
||||
{
|
||||
print_error_at(decl->span, "This declaration cannot be generic.");
|
||||
return false;
|
||||
}
|
||||
parse_attach_generics(c, generics);
|
||||
}
|
||||
if (!generics && c->unit->default_generic_section)
|
||||
if (!generics && c->unit->default_generic_section && can_be_generic)
|
||||
{
|
||||
generics = c->unit->default_generic_section;
|
||||
}
|
||||
@@ -2318,7 +2324,7 @@ static inline Decl *parse_alias_type(ParseContext *c, AstId contracts)
|
||||
{
|
||||
advance_and_verify(c, TOKEN_ALIAS);
|
||||
|
||||
Decl *decl = decl_new(DECL_POISONED, symstr(c), c->span);
|
||||
Decl *decl = decl_new(DECL_TYPE_ALIAS, symstr(c), c->span);
|
||||
DEBUG_LOG("Parse def %s", decl->name);
|
||||
if (!try_consume(c, TOKEN_TYPE_IDENT))
|
||||
{
|
||||
|
||||
@@ -251,9 +251,6 @@ static void register_generic_decls(CompilationUnit *unit, Decl **decls)
|
||||
case DECL_POISONED:
|
||||
continue;
|
||||
case DECL_FAULT:
|
||||
PRINT_ERROR_AT(decl, "Generic modules cannot use 'faultdef', place the declaration in a separate sub module or parent module instead.");
|
||||
decl_poison(decl);
|
||||
break;
|
||||
case DECL_BODYPARAM:
|
||||
case DECL_DECLARRAY:
|
||||
case DECL_ENUM_CONSTANT:
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
module abc {Type};
|
||||
|
||||
attrdef @Hello = @inline;
|
||||
faultdef ABC; // #error: Generic modules cannot use 'faultdef'
|
||||
faultdef ABC;
|
||||
|
||||
module bcd;
|
||||
|
||||
import abc;
|
||||
fn void main()
|
||||
{
|
||||
Abc{int} a;
|
||||
int? a = abc::ABC~;
|
||||
}
|
||||
7
test/test_suite/generic/generic_fault2.c3t
Normal file
7
test/test_suite/generic/generic_fault2.c3t
Normal file
@@ -0,0 +1,7 @@
|
||||
module g{T};
|
||||
|
||||
faultdef F0, F1;
|
||||
|
||||
module main;
|
||||
|
||||
fn void main() {}
|
||||
Reference in New Issue
Block a user