diff --git a/src/check_expr.cpp b/src/check_expr.cpp index 13b578084..28713880f 100644 --- a/src/check_expr.cpp +++ b/src/check_expr.cpp @@ -9274,7 +9274,12 @@ gb_internal ExprKind check_call_expr(CheckerContext *c, Operand *operand, Ast *c break; case ProcTailing_must_tail: is_call_tailed = true; - if (c->curr_proc_sig == nullptr || !are_types_identical(c->curr_proc_sig, pt)) { + if (pt->kind == Type_Proc && !is_calling_convention_must_tail_allowed(pt->Proc.calling_convention)) { + ERROR_BLOCK(); + error(call, "'#must_tail' cannot be applied to a call of a procedure with the \"%s\" calling convention", + proc_calling_convention_strings[pt->Proc.calling_convention]); + error_line("\tSuggestion: Use the \"preserve/none\" calling convention\n"); + } else if (c->curr_proc_sig == nullptr || !are_types_identical(c->curr_proc_sig, pt)) { ERROR_BLOCK(); gbString a = type_to_string(pt); gbString b = type_to_string(c->curr_proc_sig); diff --git a/src/types.cpp b/src/types.cpp index d39fcb901..808d4aebf 100644 --- a/src/types.cpp +++ b/src/types.cpp @@ -1224,6 +1224,14 @@ gb_internal bool is_calling_convention_odin(ProcCallingConvention calling_conven return false; } +gb_internal bool is_calling_convention_must_tail_allowed(ProcCallingConvention calling_convention) { + switch (calling_convention) { + case ProcCC_Odin: + return false; + } + return true; +} + gb_internal Type *alloc_type_tuple() { Type *t = alloc_type(Type_Tuple); return t;