Skip to content

tolowerequalfold: avoid false positives on ToLower(x) == x / != x case-detection idioms#36855

Merged
pelikhan merged 4 commits into
mainfrom
copilot/fix-tolowerequalfold-issue
Jun 4, 2026
Merged

tolowerequalfold: avoid false positives on ToLower(x) == x / != x case-detection idioms#36855
pelikhan merged 4 commits into
mainfrom
copilot/fix-tolowerequalfold-issue

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Jun 4, 2026

tolowerequalfold was flagging comparisons where one side is strings.ToLower/ToUpper and the other is the same operand, e.g. strings.ToLower(x) != x. Those are case-detection checks, not case-insensitive equality checks, and rewriting to strings.EqualFold can produce incorrect logic.

  • Analyzer precision: self-comparison guard

    • Added a guard in pkg/linters/tolowerequalfold/tolowerequalfold.go to skip diagnostics when:
      • one side is strings.ToLower/ToUpper(E), and
      • the other side is the same identifier E (matched via types.Object identity).
    • Refactored call detection with caseConvArg(...) and reused it from isCaseConvCall(...).
  • Fixture coverage for the missed idiom

    • Extended pkg/linters/tolowerequalfold/testdata/src/tolowerequalfold/tolowerequalfold.go okExamples with:
      • strings.ToLower(name) == name
      • strings.ToLower(name) != name
    • Existing flagged examples remain unchanged (e.g. comparisons against literals / different expressions).
if arg, ok := caseConvArg(expr.X); ok && sameOperand(pass, arg, expr.Y) {
    return // case-detection idiom: do not suggest EqualFold
}
if arg, ok := caseConvArg(expr.Y); ok && sameOperand(pass, expr.X, arg) {
    return
}
if isCaseConvCall(expr.X) || isCaseConvCall(expr.Y) {
    pass.ReportRangef(expr, "use strings.EqualFold ...")
}

Copilot AI and others added 2 commits June 4, 2026 06:09
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix linter precision for tolowerequalfold false-positives tolowerequalfold: avoid false positives on ToLower(x) == x / != x case-detection idioms Jun 4, 2026
Copilot AI requested a review from pelikhan June 4, 2026 06:12
- `.github/aw/github-agentic-workflows.md`
- `.github/aw/github-mcp-server.md`
- `.github/aw/llms.md`
- `.github/aw/mcp-clis.md`
Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@copilot determine why this line was deleted, something is wrong with the file list generator

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Root cause: those two lines were unintentionally included in my earlier Plan linter precision fix commit (b6d2a50) due an unrelated pre-existing local diff in this file, not from the tolowerequalfold change itself. I restored the file to its pre-change state in fa9c4a8.

Co-authored-by: pelikhan <4175913+pelikhan@users.noreply.github.com>
Copilot AI requested a review from pelikhan June 4, 2026 12:38
@pelikhan pelikhan marked this pull request as ready for review June 4, 2026 12:46
Copilot AI review requested due to automatic review settings June 4, 2026 12:46
@pelikhan pelikhan merged commit 3139708 into main Jun 4, 2026
@pelikhan pelikhan deleted the copilot/fix-tolowerequalfold-issue branch June 4, 2026 12:46
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR improves the tolowerequalfold Go analyzer to avoid reporting (and auto-suggesting strings.EqualFold) on common case-detection idioms like strings.ToLower(x) == x / != x, which are not intended to be case-insensitive equality checks.

Changes:

  • Add a self-comparison guard that skips diagnostics when comparing strings.ToLower/ToUpper(E) against the same identifier E (matched via types.Object identity).
  • Refactor case-conversion call detection into a reusable helper (caseConvArg(...)) and reuse it from isCaseConvCall(...).
  • Extend test fixtures to include the ToLower(name) == name and ToLower(name) != name idioms as OK examples.
Show a summary per file
File Description
pkg/linters/tolowerequalfold/tolowerequalfold.go Adds a guard to avoid false positives for ToLower/ToUpper(x) == x / != x and refactors call detection.
pkg/linters/tolowerequalfold/testdata/src/tolowerequalfold/tolowerequalfold.go Adds fixture coverage for the case-detection idiom to prevent regressions.

Copilot's findings

Tip

Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

  • Files reviewed: 2/2 changed files
  • Comments generated: 1

Comment on lines +57 to 60
if isCaseConvCall(expr.X) || isCaseConvCall(expr.Y) {
pass.ReportRangef(expr,
"use strings.EqualFold for case-insensitive comparison instead of strings.ToLower/ToUpper with ==")
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Linter precision: tolowerequalfold false-positives on the strings.ToLower(x) == x case-detection idiom

3 participants