Class DoubleNegationOrError

java.lang.Object
org.ek9lang.compiler.phase1.DoubleNegationOrError
All Implemented Interfaces:
Consumer<EK9Parser.ExpressionContext>

final class DoubleNegationOrError extends Object implements Consumer<EK9Parser.ExpressionContext>
E08274 (Steve, 2026-10-08, C1, Q8, Q9): a negation is never applied to a negation - not not b, ~~b, - -x, not ~b, - ~x, ~ -x and the same PARENTHESISED, not (not b), ~(~b), -(-x), -(not b), are compile errors.

The rule is keyed on the OPERATOR, not its spelling (Q9): word not, ~ and unary - all call _negate (BinaryExpressions.isNegation(EK9Parser.ExpressionContext), through OperatorMap.getPrefixForward, the mapping IR generation lowers them through). Applied twice they cancel out, so the expression is its operand: almost always a slip - a doubled word, or one negation too many after an edit. Parentheses do not change that (Q8): they group, and not (not b) is still b, so they are looked through. Binary - (subtraction) is not a negation - -(a - b) and a - -b are legal - and --x is the decrement token, a syntax error before this rule is reached.

Why a code of its own and not E08273: E08273 asks for parentheses to choose between two READINGS, and its fix-it (~(not b)) would leave the double negation in place. Here there is only one reading and the fix is deletion; which deletion (the operand, or a single negation) cannot be known, so there is NO auto-repair.

Reported once, on the OUTERMOST negation of a chain (not not not b is one error), with the fix the chain's count gives: an even count is the operand itself, an odd count a single negation spelt as the one written next to the operand (- - -x gives -x, not not not b gives not b, ~ ~ ~b gives ~b). A negative literal folds its sign in (-5 calls nothing), but it is spelt with a negation, so - -5 is reported too, with the fix 5. Purely syntactic, so it runs in phase 1 over the parse tree (see BinaryExpressions).