diff --git a/releasenotes.md b/releasenotes.md index b1f8f082d..f37240b6b 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -29,6 +29,7 @@ - `opt` project setting now properly documented. - Incorrect justify formatting of integers. - Assertion with duplicate function pointer signatures #1286 +- Distinct func type would not accept direct function address assign. #1287 ### Stdlib changes diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index 8c187aab3..9ff2345ce 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1193,7 +1193,17 @@ static bool rule_to_distinct(CastContext *cc, bool is_explicit, bool is_silent) assert(from_type == from_type->canonical); Type *flat = type_flatten(cc->to); ConvGroup flat_group = type_to_group(flat); - if (sema_cast_const(cc->expr)) + Expr *expr = cc->expr; + bool is_const = sema_cast_const(expr); + // Allow DistinctFooFn a = &myfunc; + if (!is_const && from_type->type_kind == TYPE_FUNC_PTR + && expr->expr_kind == EXPR_UNARY && expr->unary_expr.operator == UNARYOP_ADDR + && expr->unary_expr.expr->expr_kind == EXPR_IDENTIFIER + && expr->unary_expr.expr->identifier_expr.decl->decl_kind == DECL_FUNC) + { + is_const = true; + } + if (is_const) { cc->to = flat; cc->to_group = flat_group; diff --git a/test/test_suite/distinct/distinct_function.c3t b/test/test_suite/distinct/distinct_function.c3t new file mode 100644 index 000000000..fe2966e92 --- /dev/null +++ b/test/test_suite/distinct/distinct_function.c3t @@ -0,0 +1,14 @@ +module output; + +def FnA = fn void(int*); +distinct FnB = FnA; + +fn void func(int*) {} + +fn void main() +{ + FnA a = &func; + FnB b = (FnB)&func; + FnB b2 = &func; + FnB b3 = fn (int* x) {}; +} \ No newline at end of file