Lambda / function type would accidentally be processed as a method.

This commit is contained in:
Christoffer Lerno
2024-09-15 22:12:03 +02:00
parent 9bb45cb6a3
commit 06a083bafc
5 changed files with 23 additions and 11 deletions

View File

@@ -27,6 +27,7 @@
- Use atexit to fix finalizers on Windows #1361.
- Fix bugs in "trap-on-wrap" #1434.
- Bug with casting anyfault to error.
- Lambda / function type would accidentally be processed as a method.
### Stdlib changes
- Additional init functions for hashmap.

View File

@@ -11,7 +11,7 @@
static inline bool sema_analyse_func_macro(SemaContext *context, Decl *decl, AttributeDomain domain, bool *erase_decl);
static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *erase_decl);
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfoId type_parent, bool is_export);
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export);
static inline bool sema_analyse_main_function(SemaContext *context, Decl *decl);
static inline bool sema_check_param_uniqueness_and_type(SemaContext *context, Decl **decls, Decl *current,
unsigned current_index, unsigned count);
@@ -1084,7 +1084,7 @@ ERROR:
return decl_poison(decl);
}
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfoId type_parent, bool is_export)
static inline bool sema_analyse_signature(SemaContext *context, Signature *sig, TypeInfo *method_parent, bool is_export)
{
Variadic variadic_type = sig->variadic;
Decl **params = sig->params;
@@ -1133,7 +1133,6 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
"consider using varargs.", MAX_PARAMS);
}
TypeInfo *method_parent = type_infoptrzero(type_parent);
if (method_parent)
{
if (!sema_resolve_type_info(context, method_parent,
@@ -1233,7 +1232,7 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
SEMA_ERROR(param, "Only regular parameters are allowed for functions.");
return decl_poison(param);
}
if (!is_macro_at_name && (!type_parent || i != 0 || var_kind != VARDECL_PARAM_REF))
if (!is_macro_at_name && (!method_parent || i != 0 || var_kind != VARDECL_PARAM_REF))
{
SEMA_ERROR(param, "Ref and expression parameters are not allowed in function-like macros. Prefix the macro name with '@'.");
return decl_poison(param);
@@ -1324,12 +1323,12 @@ static inline bool sema_analyse_signature(SemaContext *context, Signature *sig,
return true;
}
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, CallABI abi, Signature *signature)
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, TypeInfo *parent, CallABI abi, Signature *signature)
{
// Get param count and variadic type
Decl **params = signature->params;
if (!sema_analyse_signature(context, signature, func_decl->func_decl.type_parent, func_decl->is_export)) return false;
if (!sema_analyse_signature(context, signature, parent, func_decl->is_export)) return false;
Variadic variadic_type = signature->variadic;
@@ -1363,7 +1362,7 @@ static inline bool sema_analyse_fntype(SemaContext *context, Decl *decl, bool *e
if (!sema_analyse_attributes(context, decl, decl->attributes, ATTR_DEF, erase_decl)) return decl_poison(decl);
if (*erase_decl) return true;
Signature *sig = &decl->fntype_decl;
return sema_analyse_function_signature(context, decl, sig->abi, sig);
return sema_analyse_function_signature(context, decl, NULL, sig->abi, sig);
}
static inline bool sema_analyse_typedef(SemaContext *context, Decl *decl, bool *erase_decl)
@@ -3325,7 +3324,7 @@ static inline bool sema_analyse_func(SemaContext *context, Decl *decl, bool *era
}
decl->type = type_new_func(decl, sig);
if (!sema_analyse_function_signature(context, decl, sig->abi, sig)) return decl_poison(decl);
if (!sema_analyse_function_signature(context, decl, type_infoptrzero(decl->func_decl.type_parent), sig->abi, sig)) return decl_poison(decl);
TypeInfo *rtype_info = type_infoptr(sig->rtype);
assert(rtype_info);
Type *rtype = rtype_info->type->canonical;
@@ -3493,7 +3492,8 @@ static inline bool sema_analyse_macro(SemaContext *context, Decl *decl, bool *er
if (!sema_analyse_func_macro(context, decl, ATTR_MACRO, erase_decl)) return false;
if (*erase_decl) return true;
if (!sema_analyse_signature(context, &decl->func_decl.signature, decl->func_decl.type_parent,
if (!sema_analyse_signature(context, &decl->func_decl.signature,
type_infoptrzero(decl->func_decl.type_parent),
false)) return false;
if (!decl->func_decl.signature.is_at_macro && decl->func_decl.body_param && !decl->func_decl.signature.is_safemacro)

View File

@@ -8299,7 +8299,7 @@ static inline bool sema_expr_analyse_lambda(SemaContext *context, Type *target_t
decl->name = scratch_buffer_copy();
decl->extname = decl->name;
decl->type = type_new_func(decl, sig);
if (!sema_analyse_function_signature(context, decl, sig->abi, sig)) return false;
if (!sema_analyse_function_signature(context, decl, NULL, sig->abi, sig)) return false;
if (flat && flat->pointer->function.prototype->raw_type != decl->type->function.prototype->raw_type)
{
RETURN_SEMA_ERROR(expr, "The lambda has type %s, which doesn't match the required type %s.",

View File

@@ -106,7 +106,7 @@ bool sema_analyse_asm(SemaContext *context, AsmInlineBlock *block, Ast *asm_stmt
bool sema_bit_assignment_check(SemaContext *context, Expr *right, Decl *member);
CondResult sema_check_comp_time_bool(SemaContext *context, Expr *expr);
bool sema_expr_check_assign(SemaContext *context, Expr *expr);
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, CallABI abi, Signature *signature);
bool sema_analyse_function_signature(SemaContext *context, Decl *func_decl, TypeInfo *parent, CallABI abi, Signature *signature);
ConstInitializer *sema_merge_bitstruct_const_initializers(ConstInitializer *lhs, ConstInitializer *rhs, BinaryOp op);
void sema_invert_bitstruct_const_initializer(ConstInitializer *initializer);
ArrayIndex sema_len_from_const(Expr *expr);

View File

@@ -0,0 +1,11 @@
import std;
def MaybeInt = maybe::Maybe(<int>);
def Func = fn void (args...);
fn int main() {
Func t;
MaybeInt m = maybe::EMPTY(<int>);
io::printfn("%s %s", m.value, m.has_value);
return 0;
}