diff --git a/releasenotes.md b/releasenotes.md index b3888b902..f218cfa4b 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -13,6 +13,7 @@ - $$memcpy_inline and $$memset_inline fixed. - `.$Type = ...` and `.$foo = ...` now works #1156. - `int.min` incorrect behaviour #1154. +- Bitstruct cast to other bitstruct by way of underlying type would fail #1159. ### Stdlib changes - Added `new_aligned` and `alloc_aligned` functions to prevent accidental under-alignment when allocating simd. diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index d42dfdff1..5c7086188 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1528,8 +1528,13 @@ static void cast_int_arr_to_bitstruct(SemaContext *context, Expr *expr, Type *ty { if (expr->expr_kind == EXPR_CAST && expr->cast_expr.kind == CAST_BSINTARR) { - expr_replace(expr, exprptr(expr->cast_expr.expr)); - return; + Expr *inner = exprptr(expr->cast_expr.expr); + if (type_flatten(inner->type) == type_flatten(type)) + { + expr_replace(expr, inner); + expr->type = type; + return; + } } insert_runtime_cast(expr, CAST_INTARRBS, type); } diff --git a/test/test_suite/bitstruct/bitstruct_cast_and_back.c3 b/test/test_suite/bitstruct/bitstruct_cast_and_back.c3 new file mode 100644 index 000000000..7956f3f52 --- /dev/null +++ b/test/test_suite/bitstruct/bitstruct_cast_and_back.c3 @@ -0,0 +1,15 @@ +// See issue #1159 + +bitstruct Foo : int { + bool a; +} + +bitstruct Bar : int { + bool a; + bool b; +} + +fn void bitstruct_cast() { + Bar bar; + Foo foo = (Foo)(int)bar; +}