Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions lint/lostresource/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,8 +114,9 @@ returning path transfers its cleanup obligation. Bound release methods capture
their original receiver even when its variable is subsequently overwritten.
An unused cleanup closure does not count as cleanup. Deferred closures read their
captured variables at return; receiver defers capture the handle immediately.
Diagnostics point to the acquisition and carry related information identifying
the return or overwrite that loses it.
Diagnostics point to the acquisition and include the line of the return or
overwrite that loses it. Keeping both in one diagnostic lets a deliberate
`nolint:lostresource` exception suppress the entire finding.

Returning a handle, storing it in a field or aggregate, sending it on a channel,
or passing it to a configured consumer transfers the obligation. The receiving
Expand Down
6 changes: 4 additions & 2 deletions lint/lostresource/flow.go
Original file line number Diff line number Diff line change
Expand Up @@ -120,10 +120,12 @@ func (f *Flow) Check(def ast.Node, call *ast.CallExpr, v *types.Var) {
continue
}
if loss := f.search(block, i+1, state, make(map[string]bool)); loss != nil {
line := strconv.Itoa(f.pass.Fset.Position(loss.Pos()).Line)
f.pass.Report(analysis.Diagnostic{
Pos: call.Pos(), End: call.End(),
Message: v.Name() + " from " + functionName(f.pass.TypesInfo, call) + " is not released or transferred on all paths; use " + f.resource.cleanup(),
Related: []analysis.RelatedInformation{{Pos: loss.Pos(), Message: "this path loses " + v.Name() + " without releasing or transferring it"}},
// Keep the witness in the same diagnostic so driver-level nolint
// filtering cannot leave a separately reported witness behind.
Message: v.Name() + " from " + functionName(f.pass.TypesInfo, call) + " is not released or transferred on all paths; lost at line " + line + "; use " + f.resource.cleanup(),
})
}
return
Expand Down