From f785e6ab3e9ef8b34fe215cc32874839911a1624 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9rald=20Barr=C3=A9?= Date: Tue, 22 Sep 2026 21:02:05 -0400 Subject: [PATCH] Fix MA0073 false positive on user-defined equality operators --- docs/Rules/MA0073.md | 2 ++ ...AvoidComparisonWithBoolConstantAnalyzer.cs | 7 +++++++ ...ComparisonWithBoolConstantAnalyzerTests.cs | 19 +++++++++++++++++++ 3 files changed, 28 insertions(+) diff --git a/docs/Rules/MA0073.md b/docs/Rules/MA0073.md index 4f35f2d5c..3e34e378c 100644 --- a/docs/Rules/MA0073.md +++ b/docs/Rules/MA0073.md @@ -24,3 +24,5 @@ if (!value) { } ``` + +The rule only reports the built-in `bool` equality operators. It does not report the comparisons that use a user-defined operator, such as `operator ==(MyType, bool)`, as removing the constant would change the meaning of the code. diff --git a/src/Meziantou.Analyzer/Rules/AvoidComparisonWithBoolConstantAnalyzer.cs b/src/Meziantou.Analyzer/Rules/AvoidComparisonWithBoolConstantAnalyzer.cs index 28ee3362d..6a3e9b1b8 100644 --- a/src/Meziantou.Analyzer/Rules/AvoidComparisonWithBoolConstantAnalyzer.cs +++ b/src/Meziantou.Analyzer/Rules/AvoidComparisonWithBoolConstantAnalyzer.cs @@ -34,6 +34,10 @@ private static void AnalyzeBinaryOperation(OperationAnalysisContext context) return; } + // Only the built-in bool operators can be replaced by the operand + if (binaryOperation.OperatorMethod is not null) + return; + // There must be 2 valid operands if (binaryOperation.LeftOperand?.Type is null || binaryOperation.RightOperand?.Type is null) return; @@ -63,6 +67,9 @@ private static void AnalyzeBinaryOperation(OperationAnalysisContext context) return; } + if (!nodeToKeep.Type.IsBoolean()) + return; + // The fixer will need to prefix the remaining operand with '!' if the original comparison is "!= true" or "== false" var logicalNotOperatorNeeded = (bool)nodeToRemove.ConstantValue.Value! ? binaryOperation.OperatorKind == BinaryOperatorKind.NotEquals : diff --git a/tests/Meziantou.Analyzer.Test/Rules/AvoidComparisonWithBoolConstantAnalyzerTests.cs b/tests/Meziantou.Analyzer.Test/Rules/AvoidComparisonWithBoolConstantAnalyzerTests.cs index 4d2d8d665..b2409df5f 100644 --- a/tests/Meziantou.Analyzer.Test/Rules/AvoidComparisonWithBoolConstantAnalyzerTests.cs +++ b/tests/Meziantou.Analyzer.Test/Rules/AvoidComparisonWithBoolConstantAnalyzerTests.cs @@ -390,4 +390,23 @@ void Test(long? number) return test.RunAsync(); } + + [Fact] + public Task ComparingWithUserDefinedOperator_NoDiagnosticReported() + { + var test = CreateTest(); + test.TestCode = """ + class C + { + public static bool operator ==(C a, bool b) => true; + public static bool operator !=(C a, bool b) => false; + public override bool Equals(object o) => true; + public override int GetHashCode() => 0; + + bool M(C c) => c == true; + } + """; + + return test.RunAsync(); + } }