Bitstructs no longer overloadable with bitops. #2374

This commit is contained in:
Christoffer Lerno
2025-08-06 14:51:32 +02:00
parent aae873c044
commit 1d25197bfd
4 changed files with 40 additions and 10 deletions

View File

@@ -23,6 +23,7 @@
- Fixed bug generating `$c += 1` when `$c` was derived from a pointer but behind a cast.
- Compiler segfault when using bitwise not on number literal cast to bitstruct #2373.
- Formatter did not properly handle "null" for any, and null for empty faults. #2375
- Bitstructs no longer overloadable with bitops. #2374
### Stdlib changes
- Add `==` to `Pair`, `Triple` and TzDateTime. Add print to `Pair` and `Triple`.

View File

@@ -2059,9 +2059,9 @@ const char *operator_overload_to_string(OperatorOverload operator_overload)
case OVERLOAD_ELEMENT_AT:
case OVERLOAD_ELEMENT_REF:
case OVERLOAD_ELEMENT_SET:
case OVERLOAD_LEN:
case OVERLOAD_NEGATE:
case OVERLOAD_UNARY_MINUS: UNREACHABLE
case OVERLOAD_LEN: UNREACHABLE
case OVERLOAD_NEGATE: return "~";
case OVERLOAD_UNARY_MINUS: return "-";
case OVERLOAD_PLUS: return "+";
case OVERLOAD_MINUS: return "-";
case OVERLOAD_MULTIPLY: return "*";
@@ -2445,6 +2445,26 @@ INLINE bool sema_analyse_operator_method(SemaContext *context, Type *parent_type
return false;
}
if (parent_type->canonical->type_kind == TYPE_BITSTRUCT)
{
switch (operator)
{
case OVERLOAD_XOR:
case OVERLOAD_AND:
case OVERLOAD_OR:
case OVERLOAD_XOR_ASSIGN:
case OVERLOAD_AND_ASSIGN:
case OVERLOAD_OR_ASSIGN:
case OVERLOAD_NEGATE:
{
SourceSpan span = method_find_overload_span(method);
RETURN_SEMA_ERROR_AT(span, "Bitstructs do not support overloading the '%s' operator.",
operator_overload_to_string(operator));
}
default:
break;
}
}
// Check that actual types match up
Type *value;
Type *index_type;

View File

@@ -6961,6 +6961,7 @@ static bool sema_expr_analyse_op_assign_enum_ptr(SemaContext *context, Expr *rhs
}
return true;
}
/**
* Analyse *= /= %= ^= |= &= += -= <<= >>=
*
@@ -7026,12 +7027,7 @@ static bool sema_expr_analyse_op_assign(SemaContext *context, Expr *expr, Expr *
Type *canonical = no_fail->canonical;
if (type_is_user_defined(canonical))
{
if (canonical->type_kind == TYPE_BITSTRUCT)
{
if (operator == BINARYOP_BIT_OR_ASSIGN
|| operator == BINARYOP_BIT_AND_ASSIGN
|| operator == BINARYOP_BIT_XOR_ASSIGN) goto SKIP_OVERLOAD_CHECK;
}
if (canonical->type_kind == TYPE_BITSTRUCT && is_bit_op) goto SKIP_OVERLOAD_CHECK;
BoolErr b = sema_insert_overload_in_op_assign_or_error(context, expr, left, right, operator, no_fail->canonical);
if (b == BOOL_ERR) return false;
if (b == BOOL_TRUE) return true;
@@ -8589,7 +8585,6 @@ VALID_VEC:
// 3. The simple case, non-const.
if (!expr_const_foldable_unary(inner, UNARYOP_BITNEG))
{
expr->type = inner->type;
return true;
}

View File

@@ -0,0 +1,14 @@
bitstruct Foo : uint
{
bool test : 2;
}
fn bool Foo.test(self, Foo other) @operator(==) => true;
fn Foo Foo.and(self, uint other) @operator(&) => (Foo)(((uint)self) & other); // #error: Bitstructs do not support
fn Foo Foo.or(self, uint other) @operator(|) => (Foo)(((uint)self) | other); // #error: Bitstructs do not support
fn void Foo.and_eq(&self, uint other) @operator(&=) => *self = (Foo)(((uint)*self) & other); // #error: Bitstructs do not support
fn void Foo.or_eq(&self, uint other) @operator(|=) => *self = (Foo)(((uint)*self) | other); // #error: Bitstructs do not support
fn Foo Foo.neg(self) @operator(~) { return {}; } // #error: Bitstructs do not support