diff --git a/src/compiler/sema_casts.c b/src/compiler/sema_casts.c index ad21d1869..95ee1cbfd 100644 --- a/src/compiler/sema_casts.c +++ b/src/compiler/sema_casts.c @@ -1107,6 +1107,11 @@ bool cast_implicit(Expr *expr, Type *to_type) } } cast(expr, to_type); + // Allow narrowing after widening + if (type_is_numeric(to_type) && expr->expr_kind == EXPR_CONST && type_size(expr_canonical) < type_size(to_canonical)) + { + expr->const_expr.narrowable = true; + } if (expr->expr_kind == EXPR_CAST) expr->cast_expr.implicit = true; return true; } diff --git a/test/test_suite/expressions/casts/narrowing.c3 b/test/test_suite/expressions/casts/narrowing.c3 new file mode 100644 index 000000000..983d0af78 --- /dev/null +++ b/test/test_suite/expressions/casts/narrowing.c3 @@ -0,0 +1,7 @@ +fn int main() +{ + ushort x; + uint y; + ushort z = x + (ushort)(0x12); + return 0; +} \ No newline at end of file diff --git a/test/test_suite/symbols/various.c3 b/test/test_suite/symbols/various.c3 index 81b42ee3d..6e4ba7ac6 100644 --- a/test/test_suite/symbols/various.c3 +++ b/test/test_suite/symbols/various.c3 @@ -117,7 +117,7 @@ fn void test16() int i = 1; ichar c = 1 ? 'c' : 'd'; - ichar d = 1 ? 'c' : i; // #error: 'int' to 'ichar' + ichar d = 1 ? 'c' : i; ichar e = 1 ? i : 0; // #error: 'int' to 'ichar' int g = 1 ? i : f; // #error: 'float' to 'int' int a = f ? 1 : 0;