Skip to content

fix(ioutildeprecated): report dot-imported Discard used as a selector receiver - #75295

Merged
pelikhan merged 2 commits into
mainfrom
sergo/ioutildeprecated-dot-import-receiver-r121-377a88d4d227732a
Nov 6, 2026
Merged

pelikhan merged 2 commits into
mainfrom
sergo/ioutildeprecated-dot-import-receiver-r121-377a88d4d227732a

Conversation

@github-actions

@github-actions github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor

Summary

ioutildeprecated's dot-import pass (checkDotImportIoutilUsage) skipped every identifier whose parent is an *ast.SelectorExpr. The intent was to skip the Sel side (ioutil.X is handled by checkQualifiedIoutilUsage, and x.Discard could be a field). But the check also skipped the X side, so a dot-imported receiver was never reported:

import . "io/ioutil"

_, _ = Discard.Write(p) // previously: no diagnostic

Discard is the only entry in replacements that is a value with methods, so it's the only name that can appear as a selector receiver.

Fix

if sel, ok := cur.Parent().Node().(*ast.SelectorExpr); ok && sel.Sel == ident {
	continue
}

The X side of a qualified ioutil.Discard is the ioutil identifier. It resolves to a *types.PkgName owned by the importing package, not io/ioutil, so this change can't double-report qualified uses.

Tests

  • dot_import.go: new BadDotDiscardMethod (Discard.Write(...), which was the false negative) and BadDotDiscard (plain dot-imported value) as a baseline.
  • ioutildeprecated.go:
    • New BadDiscardMethod (ioutil.Discard.Write(...)) expects exactly one diagnostic, guarding against double reports.
    • New GoodFieldNamedDiscard checks that a struct field named Discard is still not reported.

Evidence and validation

  • The gap came from auditing all cursor.Parent() uses in pkg/linters (Sergo run 121). osisnotexist and astutil.IsGoOrDeferClosure already handle intermediate nodes correctly. This was the only over-broad parent check.
  • βœ… get_diagnostics_for_file (gopls via Serena) reports 0 diagnostics on ioutildeprecated.go. Both fixtures type-check with no errors. gopls's deprecated analyzer also reports ioutil.Discard.Write once, which matches the new expectation.
  • βœ… No production code dot-imports io/ioutil, so this CI-enforced linter won't report anything new on existing code.
  • ⚠️ go test was denied by the sandbox in this run, so analysistest hasn't run. Please let CI run go test ./pkg/linters/ioutildeprecated/.

πŸ€– Generated with [Claude Code]((claude.com/redacted)

Generated by πŸ€– Sergo - Serena Go Expert Β· claude Β· routed: opus55 high Β· ~236 AIC Β· βŒ– ~2 AIC Β· ⊞ 3.8K Β· β—·

  • expires on Nov 12, 2026, 7:56 PM UTC-08:00

@github-actions github-actions Bot added cookie Issue Monster Loves Cookies! sergo labels Nov 6, 2026
@pelikhan
pelikhan marked this pull request as ready for review November 6, 2026 03:57
Copilot AI auto review requested due to automatic review settings November 6, 2026 03:57
@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

βœ… PR Specification Reviewer completed successfully!

PR Specification Reviewer

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from PR Specification Reviewer Β· gpt56 Β· ~1 AIC Β· βŒ– ~1 AIC Β· ⊞ 1.6K Β· β—·

Generated by PR Specification Reviewer for #75295

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

βœ… Ponytail Reviewer completed successfully!

Ponytail Reviewer

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from Ponytail Reviewer Β· routed: gpt56 max Β· ~2 AIC Β· βŒ– ~1 AIC Β· ⊞ 118 Β· β—·

Generated by Ponytail Reviewer for #75295

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

βœ… Design Decision Gate πŸ—οΈ completed the design decision gate check. See the comment below for the result and any generated ADR draft.

Design Decision Gate πŸ—οΈ

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from Design Decision Gate πŸ—οΈ Β· routed: gpt56 max Β· ~1 AIC Β· βŒ– ~2 AIC Β· ⊞ 7.7K Β· β—·

πŸ—οΈ ADR gate enforced by Design Decision Gate πŸ—οΈ

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

🧠 Matt Pocock Skills Reviewer failed to deliver outputs during the skills-based review.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

βœ… PR Code Quality Reviewer completed the code quality review.

πŸ”Ž Code quality review by PR Code Quality Reviewer

@github-actions

github-actions Bot commented Nov 6, 2026 •

Copy link
Copy Markdown
Contributor Author

βœ… Test Quality Sentinel completed test quality analysis.

Test Quality Sentinel

Outcome: reported_no_action

The agent completed and reported no action. A no-op output alone does not verify that all required work was completed or that publication was possible.

Agent messages are omitted from this comment. The category uses structured run status, not interpretation of agent prose.

Generated from Test Quality Sentinel Β· routed: gpt56 max Β· ~1 AIC Β· βŒ– ~1 AIC Β· ⊞ 6.3K Β· β—·

πŸ§ͺ Test quality analysis by Test Quality Sentinel

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟒 Approval recommended

No active review issues are reported for the linter’s dot-imported receiver fix.

No open issues πŸŽ‰

What changed in this PR

This PR fixes a missed diagnostic in gh-aw’s ioutildeprecated linter for dot-imported Discard used as a selector receiver, such as Discard.Write(p).

Changes:

  • Skip only selector member identifiers, allowing dot-imported receivers to be checked.
  • Add regression fixtures for dot-imported values and method calls.
  • Add fixtures guarding against duplicate diagnostics on qualified calls and false positives on fields named Discard.
File Description
pkg/​linters/​ioutildeprecated/​testdata/​src/​ioutildeprecated/​ioutildeprecated.go Adds qualified-call and field-name regression cases.
pkg/​linters/​ioutildeprecated/​testdata/​src/​ioutildeprecated/​dot_import.go Adds dot-imported Discard value and receiver cases.
pkg/​linters/​ioutildeprecated/​ioutildeprecated.go Narrows selector filtering to retain receiver checks.

Review effort: Balanced (auto)

@github-actions github-actions Bot left a comment

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.

Review summary

No actionable issues found in the changed lines. The selector-side check correctly preserves dot-imported receiver diagnostics while avoiding duplicate reports for qualified selectors; added fixtures cover the key cases.

Verification

Static review completed using the pre-fetched diff. Tests were not run because this review is source-only and the PR notes sandbox denial.

πŸ”Ž Code quality review by PR Code Quality Reviewer Β· copilot Β· gpt50 Β· ~2 AIC Β· βŒ– ~1 AIC Β· ⊞ 1.6K
Comment /review to run again

@github-actions github-actions Bot left a comment

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.

Skills-Based Review 🧠

Applied /diagnosing-bugs and /tdd. Approving: the fix is correct and well-tested. Two minor nits are left as inline comments.

πŸ“‹ Verification and key themes

Verification

  • Ran go test ./pkg/linters/ioutildeprecated/ locally with disposable caches. It passes.
  • Mutation check: with the Sel skip removed, TestIoutilDeprecated fails with unexpected double reports on every qualified ioutil.* use (including ioutil.Discard.Write at line 49). So the Sel skip is load-bearing and the new BadDiscardMethod fixture guards it.
  • Reverting only the new condition makes BadDotDiscardMethod (dot_import.go:30) fail with a missing diagnostic. The fixture guards the false negative.
  • gofmt -l is clean. No production code dot-imports io/ioutil.

Key themes

  • Root cause, not symptom: the over-broad parent check is narrowed to the exact case that was wrong.
  • Double-report guard: the qualified ioutil.Discard.Write case is covered with an exact one-diagnostic expectation.
  • Stale comment: the fixture comment describes history rather than intent (inline).
  • Negative control: GoodFieldNamedDiscard passes regardless of the Sel change, so it is not what guards the fix (inline).

Positive highlights

  • βœ… The inline comment explaining why Sel is skipped but X is kept is accurate and prevents a future regression.
  • βœ… Good use of // want fixtures for both the positive and the double-report cases.

@copilot please address the review comments above.

🧠 Reviewed using Matt Pocock's skills by Matt Pocock Skills Reviewer Β· copilot Β· routed: haiku55 xhigh Β· ~6 AIC Β· βŒ– ~1 AIC Β· ⊞ 5.4K
Comment /matt to run again

_ = Discard // want `ioutil\.Discard is deprecated; use io\.Discard instead`
}

// Discard used as a selector receiver was previously skipped because the

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.

[/diagnosing-bugs] Nit: this comment records history ("was previously skipped"), which will read as stale once the fix lands. Describing what the case guards is more durable, for example: // Discard as a selector receiver must be reported.

@copilot please address this.

Discard int
}

// A field that shares a deprecated name is not reported.

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.

[/tdd] GoodFieldNamedDiscard does not guard the Sel change. It passes even with the Sel skip removed, because a struct field is rejected by the io/ioutil package check, not the selector check. BadDiscardMethod is the test that guards the Sel skip, so keep this as a negative control but do not rely on it as a regression guard.

πŸ’‘ Verification

I removed the Sel skip entirely and re-ran go test ./pkg/linters/ioutildeprecated/. The new failures were the qualified ioutil.* double reports, and h.Discard at line 58 stayed clean.

@copilot please address this.

@gh-aw-bot

Copy link
Copy Markdown
Collaborator

@copilot

Copilot assignment requested for the following outstanding work:

  1. Update this branch with the latest main using make merge-main, resolving any conflicts and preserving the intended changes.
  2. Fix failing check safe_outputs (FAILURE): https://github.com/github/gh-aw/actions/runs/42159582345/job/127705359420.

Once you start work, post this work summary as a PR comment without the leading Copilot mention, including the Sous-chef head, work, and state lines below, to record that the assignment is running. Apply the necessary fixes on this PR's existing branch, reply to each listed review thread and resolve it when addressed. Ignore feedback already answered or resolved; stop when only human review or CI remains. Do not merge or trigger CI.

Sous-chef requested-head: 6034f1e
Sous-chef requested-work: c7cf93e497befdd5e698d00101b0703e4101fe4133d86d433f7c170d07402b7e
Sous-chef requested-state: 383b82c5ae5ac7598004e44bf187e72c0dc7824d5dd9660bd1a62cf54903baf6

Generated by πŸ‘¨πŸ³ PR Sous Chef Β· pi Β· haiku45 Β· ~6 AIC Β· βŒ– ~13 AIC Β· ⊞ 1.2K Β· β—·
Comment /souschef to run again

…d-dot-import-receiver-r121-377a88d4d227732a

Co-authored-by: gh-aw-bot <259018956+gh-aw-bot@users.noreply.github.com>
Copilot AI requested a review from gh-aw-bot November 6, 2026 04:50
@pelikhan
pelikhan merged commit c09037f into main Nov 6, 2026
44 checks passed
@pelikhan
pelikhan deleted the sergo/ioutildeprecated-dot-import-receiver-r121-377a88d4d227732a branch November 6, 2026 08:06
@github-actions

github-actions Bot commented Nov 6, 2026

Copy link
Copy Markdown
Contributor Author

πŸŽ‰ This pull request is included in a new release.

Release: v1.2.1

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

cookie Issue Monster Loves Cookies! sergo

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants