{"record":{"id":"492c102169392058","repo":"oxc-project/oxc","slug":"comparison-with-nan-will-always-return-false","errorCode":null,"errorMessage":"Comparison with NaN will always return false","messagePattern":"Comparison with NaN will always return false","errorType":"validation","errorClass":"OxcDiagnostic","httpStatus":null,"severity":"error","filePath":"crates/oxc_linter/src/rules/eslint/use_isnan.rs","lineNumber":28,"sourceCode":"use serde::Deserialize;\n\nuse crate::{\n    AstNode,\n    context::LintContext,\n    rule::{DefaultRuleConfig, Rule},\n};\n\nfn comparison_with_nan(span: Span, operator: BinaryOperator) -> OxcDiagnostic {\n    let msg = match operator {\n        BinaryOperator::Inequality | BinaryOperator::StrictInequality => {\n            \"Checking inequality with NaN will always return true\"\n        }\n        BinaryOperator::Equality | BinaryOperator::StrictEquality => {\n            \"Checking equality with NaN will always return false\"\n        }\n        _ => \"Comparison with NaN will always return false\",\n    };\n    OxcDiagnostic::warn(msg)\n        .with_help(\"Use the `isNaN` function to compare with NaN.\")\n        .with_label(span)\n}\n\nfn switch_nan(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Checking `switch` discriminant against NaN will never match\")\n        .with_help(\"Use the `isNaN` function instead of the switch.\")\n        .with_label(span)\n}\n\nfn case_nan(span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(\"Checking for NaN in `case` clause will never match\")\n        .with_help(\"Use the `isNaN` function instead of the switch.\")\n        .with_label(span)\n}\n\nfn index_of_nan(method_name: &str, span: Span) -> OxcDiagnostic {\n    OxcDiagnostic::warn(format!(","sourceCodeStart":10,"sourceCodeEnd":46,"githubUrl":"https://github.com/oxc-project/oxc/blob/e1e7af627c8843ab64044ed466b128fcc21a035b/crates/oxc_linter/src/rules/eslint/use_isnan.rs#L10-L46","documentation":"The relational arm (the match's `_` branch covering `<`, `<=`, `>`, `>=`) of oxlint's `use-isnan` rule: every ordering comparison involving NaN evaluates to false, because NaN is unordered relative to all numbers including itself. The flagged condition is dead code.","triggerScenarios":"Binary relational expressions with a NaN operand: `x < NaN`, `NaN >= limit`. Reported whenever `is_nan_identifier` matches either side of a non-equality comparison operator.","commonSituations":"Range checks written against values that may be NaN; porting math code that assumed NaN sorts like -Infinity; refactors that replaced a variable with the NaN literal.","solutions":["Remove the dead branch, or replace it with an explicit `Number.isNaN(x)` guard if NaN handling was the intent","Restructure range checks to test NaN first: `if (Number.isNaN(x)) ... else if (x < limit) ...`","Run oxlint across the project to find every relational NaN comparison"],"exampleFix":"// before — always false, clamp() is unreachable\nif (value < NaN) {\n  clamp(value);\n}\n\n// after — express the real intent explicitly\nif (Number.isNaN(value)) {\n  clamp(value);\n}","handlingStrategy":"validation","validationCode":"// .oxlintrc.json\n{ \"rules\": { \"use-isnan\": \"error\" } }\n// CI gate: npx oxlint --deny-warnings .\n// grep guard for relational NaN: rg \"[<>]=?\\s*NaN|NaN\\s*[<>]\" src/","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Check Number.isNaN(x) before any range comparison on possibly-NaN values","Remember relational NaN comparisons are silent dead code — only the linter sees them","Property-test numeric helpers with NaN inputs","Grep new code for NaN literals used as comparators"],"tags":["lint","oxlint","eslint","nan","correctness","floating-point","operators"],"backgroundTag":"nan-comparison","analyzedSha":"e1e7af627c8843ab64044ed466b128fcc21a035b","analyzedAt":"2026-08-20T07:01:07.079Z","contentChangedAt":"2026-08-20T07:01:07.079Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}