diff --git a/lib/std/collections/object.c3 b/lib/std/collections/object.c3 index c44a7765b..7e83b8d08 100644 --- a/lib/std/collections/object.c3 +++ b/lib/std/collections/object.c3 @@ -188,6 +188,7 @@ fn void Object.set_object(&self, String key, Object* new_object) @private <* @require self.allocator != null : "This object is not properly initialized, was it really created using 'new'" + @require !@typeis(value, void*) ||| value == null : "void pointers cannot be stored in an object" *> macro Object* Object.object_from_value(&self, value) @private { @@ -204,7 +205,6 @@ macro Object* Object.object_from_value(&self, value) @private $case $Type.typeid == Object*.typeid: return value; $case $Type.typeid == void*.typeid: - if (value != null) TYPE_MISMATCH?!; return &NULL_OBJECT; $case $assignable(value, String): return new_string(value, self.allocator); diff --git a/releasenotes.md b/releasenotes.md index 81b50bef1..f8356931b 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -7,6 +7,7 @@ - Add `--run-dir`, to specify directory for running executable using `compile-run` and `run` #2121. - Deprecate uXX and iXX bit suffixes. - Add experimental LL / ULL suffixes for int128 and uint128 literals. +- Allow the right hand side of `|||` and `&&&` be runtime values. ### Fixes - Assert triggered when casting from `int[2]` to `uint[2]` #2115 diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 53358dac7..a14c3a550 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -8392,15 +8392,20 @@ static inline bool sema_expr_analyse_ct_and_or(SemaContext *context, Expr *expr, ASSERT_SPAN(expr, expr->resolve_status == RESOLVE_RUNNING); bool is_and = expr->binary_expr.operator == BINARYOP_CT_AND; if (!sema_analyse_expr(context, left)) return false; - if (!expr_is_const_bool(left)) RETURN_SEMA_ERROR(left, "Expected this to evaluate to a constant boolean."); + if (!sema_cast_const(left) || !expr_is_const_bool(left)) RETURN_SEMA_ERROR(left, "Expected this to evaluate to a constant boolean."); if (left->const_expr.b != is_and) { expr_rewrite_const_bool(expr, type_bool, !is_and); return true; } if (!sema_analyse_expr(context, right)) return false; - if (!expr_is_const_bool(right)) RETURN_SEMA_ERROR(right, "Expected this to evaluate to a constant boolean."); - expr_rewrite_const_bool(expr, type_bool, right->const_expr.b); + if (sema_cast_const(right) && expr_is_const_bool(right)) + { + expr_rewrite_const_bool(expr, type_bool, right->const_expr.b); + return true; + } + if (!cast_implicit(context, right, type_bool, false)) return false; + expr_replace(expr, right); return true; } diff --git a/test/test_suite/compile_time/ct_and_or.c3 b/test/test_suite/compile_time/ct_and_or.c3 index bd2dc0a12..21f6528c7 100644 --- a/test/test_suite/compile_time/ct_and_or.c3 +++ b/test/test_suite/compile_time/ct_and_or.c3 @@ -3,4 +3,7 @@ fn void test() $assert false ||| false ||| true ||| hello(""); $assert !(false &&& hello("")); $assert !(true &&& true &&& false &&& hello("")); + int y; + bool x = true &&& y > 0; + bool z = true ||| y > 0; } \ No newline at end of file