Skip to content

Precision gap: using (field = new T()) not recognized as disposing the field #220

Description

@PhysShell

Found by: the issue #201 oracle sweep, docs/notes/oracle-sweep-2026-07-10.md; catalogued as docs/notes/field-notes-patterns.md entry 14.

The pattern

private CancellationTokenSource cts;
public void Cancel() {
    using (cts = new CancellationTokenSource()) {   // field IS the using acquisition target
        ...
    }
    // cts.Dispose() ran at the end of the using block
}

A using (expr) { } disposes whatever expr evaluates to at block exit, regardless of whether expr is a bare new T(), a pre-existing local (already handled — see field-dispose-via-* corpus fixtures / oracle-known-fps.md root-cause 1, the using (preExistingLocal) shape), or, as here, an assignment to a field.

The flow-locals detector's using-release recognition appears scoped to a local target; a field on the left-hand side of the acquisition expression inside using (...) isn't threaded back to the field-disposal scan, so the field reads as permanently un-disposed.

Evidence — ShareX/ShareX, 3 confirmed instances

  • ShareX.HelpersLib/Cryptographic/HashChecker.cs:59using (cts = new CancellationTokenSource())
  • ShareX.HelpersLib/TaskEx.cs:55using (cts = new CancellationTokenSource())
  • ShareX.IndexerLib/IndexerJson.cs:49using (jsonWriter = new JsonTextWriter(sw))

Suggested direction (not prescriptive)

When the using acquisition expression is an assignment (field = new T(...) or field = <owning-factory-call>), thread the field itself as released at the using block's exit — the same lowering already applied to using (preExistingLocal), generalized to a field-typed assignment target.

Scope

No analyzer code changed as part of the sweep — this issue tracks the fix as its own unit of work.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions