Methods registered with generic type will implicitly get templated.

This commit is contained in:
Christoffer Lerno
2025-12-30 22:39:42 +01:00
parent d51dd09a1f
commit ad8769580a
5 changed files with 64 additions and 30 deletions

View File

@@ -135,36 +135,40 @@ fn Win32_LONG exception_handler(ExceptionPointers* exception_info)
{
if (!has_panicked)
{
@stack_mem(512; Allocator allocator)
@stack_mem(4096; Allocator allocator)
{
DString s;
s.init(allocator: allocator);
Win32_DWORD code = exception_info.exception_record.exception_code;
void* addr = exception_info.exception_record.exception_address;
switch (code)
@pool_init(allocator, 2048)
{
case 0x80000001: s.appendf("Guard page violation at address %p", addr);
case 0x80000002: s.appendf("Datatype misalignment at address %p", addr);
case 0xC0000005: s.appendf("Access Violation at address %p", addr);
case 0xC0000006: s.appendf("In page error at address %p", addr);
case 0xC000001D: s.appendf("Illegal instruction at address %p", addr);
case 0xC000008C: s.appendf("Array bounds exceeded at address %p", addr);
case 0xC000008D: s.appendf("Flt denormal operand at address %p", addr);
case 0xC000008E: s.appendf("Flt divide by zero at address %p", addr);
case 0xC0000090: s.appendf("Flt invalid operation at address %p", addr);
case 0xC0000094: s.appendf("Integer divide by zero at address %p", addr);
case 0xC00000FD: s.appendf("Stack overflow at address %p", addr);
case 0xC0000096: s.appendf("Privileged instruction at address %p", addr);
case 0xC0000374: s.appendf("Heap corruption detected at address %p", addr);
case 0xC0000409: s.appendf("Stack buffer overflow at address %p", addr);
case 0xC00004A2: s.appendf("Enclave violation at address %p", addr);
default:
s.appendf("Unhandled exception (%X) at %p", code, addr);
}
if (!builtin::print_backtrace(s.str_view(), 8))
{
io::eprintfn("\nERROR: %s", s.str_view());
}
DString s;
s.init(allocator: allocator);
Win32_DWORD code = exception_info.exception_record.exception_code;
void* addr = exception_info.exception_record.exception_address;
switch (code)
{
case 0x80000001: s.appendf("Guard page violation at address %p", addr);
case 0x80000002: s.appendf("Datatype misalignment at address %p", addr);
case 0xC0000005: s.appendf("Access Violation at address %p", addr);
case 0xC0000006: s.appendf("In page error at address %p", addr);
case 0xC000001D: s.appendf("Illegal instruction at address %p", addr);
case 0xC000008C: s.appendf("Array bounds exceeded at address %p", addr);
case 0xC000008D: s.appendf("Flt denormal operand at address %p", addr);
case 0xC000008E: s.appendf("Flt divide by zero at address %p", addr);
case 0xC0000090: s.appendf("Flt invalid operation at address %p", addr);
case 0xC0000094: s.appendf("Integer divide by zero at address %p", addr);
case 0xC00000FD: s.appendf("Stack overflow at address %p", addr);
case 0xC0000096: s.appendf("Privileged instruction at address %p", addr);
case 0xC0000374: s.appendf("Heap corruption detected at address %p", addr);
case 0xC0000409: s.appendf("Stack buffer overflow at address %p", addr);
case 0xC00004A2: s.appendf("Enclave violation at address %p", addr);
default:
s.appendf("Unhandled exception (%X) at %p", code, addr);
}
if (!builtin::print_backtrace(s.str_view(), 8))
{
io::eprintfn("\nERROR: %s", s.str_view());
}
};
};
}
if (previous_filter)

View File

@@ -2557,6 +2557,7 @@ Decl *sema_find_extension_method_in_list(Decl **extensions, Type *type, const ch
bool sema_resolve_type_decl(SemaContext *context, Type *type);
bool sema_check_type_variable_array(SemaContext *context, TypeInfo *type);
Decl *sema_find_symbol(SemaContext *context, const char *symbol);
Decl *sema_find_template_symbol(SemaContext *context, const char *symbol, Path *path);
Decl *sema_find_path_symbol(SemaContext *context, const char *symbol, Path *path);
Decl *sema_find_label_symbol(SemaContext *context, const char *symbol);
Decl *sema_find_label_symbol_anywhere(SemaContext *context, const char *symbol);

View File

@@ -5568,10 +5568,30 @@ RETRY:
UNREACHABLE
}
INLINE Decl *type_is_possible_template(SemaContext *context, TypeInfo *type_info)
{
if (type_info->resolve_status == RESOLVE_DONE) return NULL;
if (type_info->kind != TYPE_INFO_IDENTIFIER) return NULL;
if (type_info->subtype != TYPE_COMPRESSED_NONE) return NULL;
Decl *candidate = sema_find_template_symbol(context, type_info->unresolved.name, type_info->unresolved.path);
return candidate && candidate->is_template ? candidate : NULL;
}
bool sema_analyse_method_register(SemaContext *context, Decl *method)
{
TypeInfo *parent_type_info = type_infoptr(method->func_decl.type_parent);
if (!sema_resolve_type_info(context, parent_type_info, method->decl_kind == DECL_MACRO ? RESOLVE_TYPE_MACRO_METHOD : RESOLVE_TYPE_FUNC_METHOD)) return false;
Decl *decl = method->is_templated ? NULL : type_is_possible_template(context, parent_type_info);
if (decl)
{
Decl *generic_section = declptr(decl->generic_id);
vec_add(generic_section->generic_decl.decls, method);
method->is_template = true;
method->generic_id = decl->generic_id;
return false;
}
else
{
if (!sema_resolve_type_info(context, parent_type_info, method->decl_kind == DECL_MACRO ? RESOLVE_TYPE_MACRO_METHOD : RESOLVE_TYPE_FUNC_METHOD)) return false;
}
// Can the type have methods?
Type *parent_type = parent_type_info->type = parent_type_info->type->canonical;

View File

@@ -1044,6 +1044,16 @@ Decl *sema_resolve_type_method(SemaContext *context, CanonicalType *type, const
}
}
Decl *sema_find_template_symbol(SemaContext *context, const char *symbol, Path *path)
{
NameResolve resolve = {
.suppress_error = true,
.symbol = symbol,
.is_parameterized = true,
};
if (!sema_resolve_symbol_common(context, &resolve)) return poisoned_decl;
return resolve.found;
}
/**
* Silently find a symbol, will return NULL, Poison or the value
*/

View File

@@ -461,7 +461,6 @@ void sema_analysis_pass_process_methods(Module *module, bool process_generic)
}
if (sema_analyse_method_register(&context, method))
{
if (method->decl_kind == DECL_MACRO)
{
vec_add(unit->macro_methods, method);