From 7cdb1ce9eb2ad2364dc50466f8f36cdf2c6a8534 Mon Sep 17 00:00:00 2001 From: Christoffer Lerno Date: Sat, 5 Jul 2025 20:40:55 +0200 Subject: [PATCH] Catch accidental `foo == BAR;` where `foo = BAR;` was most likely intended. #2274 --- releasenotes.md | 1 + src/compiler/sema_expr.c | 9 ++++++++- .../expressions/discarded_binary.c3 | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+), 1 deletion(-) create mode 100644 test/test_suite/expressions/discarded_binary.c3 diff --git a/releasenotes.md b/releasenotes.md index 2e27b438a..a10860fe4 100644 --- a/releasenotes.md +++ b/releasenotes.md @@ -9,6 +9,7 @@ - `$typeof` may return a compile time type. - Improved error messages on missing qualifier on enum value. #2260 - Add `--echo-prefix` to edit the prefix with `$echo` statements. Supports {FILE} and {LINE} +- Catch accidental `foo == BAR;` where `foo = BAR;` was most likely intended. #2274 ### Fixes - mkdir/rmdir would not work properly with substring paths on non-windows platforms. diff --git a/src/compiler/sema_expr.c b/src/compiler/sema_expr.c index 052dc00bf..255b98f18 100644 --- a/src/compiler/sema_expr.c +++ b/src/compiler/sema_expr.c @@ -11288,7 +11288,14 @@ bool sema_expr_check_discard(SemaContext *context, Expr *expr) if (expr->call_expr.has_optional_arg) goto ERROR_ARGS; return true; } - if (!IS_OPTIONAL(expr)) return true; + if (!IS_OPTIONAL(expr)) + { + if (expr->expr_kind == EXPR_BINARY && expr->binary_expr.operator == BINARYOP_EQ) + { + RETURN_SEMA_ERROR(expr, "This equals check was discarded, which isn't allowed. You can assign it to a variable or explicitly ignore it with a void cast '(void)' if this is what you want."); + } + return true; + } RETURN_SEMA_ERROR(expr, "An optional value was discarded, you can assign it to a variable, ignore it with a void cast '(void)', rethrow on optional with '!' or panic '!!' to avoid this error."); ERROR_ARGS: RETURN_SEMA_ERROR(expr, "The result of this call is optional due to its argument(s). This optional result may not be implicitly discarded. Please assign it to a variable, ignore it with '(void)', rethrow with '!' or panic with '!!'."); diff --git a/test/test_suite/expressions/discarded_binary.c3 b/test/test_suite/expressions/discarded_binary.c3 new file mode 100644 index 000000000..f1f32751a --- /dev/null +++ b/test/test_suite/expressions/discarded_binary.c3 @@ -0,0 +1,19 @@ +enum Foo +{ + COMMENT +} + +fn int main() +{ + Foo state = COMMENT; + char c; + switch (c) + { + case '#': + (void)(state == COMMENT); + state == COMMENT; // #error: This equals check was discarded + int a = 0; + a == 0; // #error: This equals check was discarded + } + return 0; +} \ No newline at end of file