Skip to content

Fix S3971 FP: Support IAsyncLifetime (xUnit v3) #9777

@dnnr

Description

@dnnr

Description

Rule S3971 raises a false positive when calling GC.SuppressFinalize in a DisposeAsync method of a class that implements IAsyncLifetime from xUnit. The interface itself inherits IAsyncDisposable, so S3971 should accept this accordingly.

Unlike what I initially assumed, this doesn't seem to be a regression of #3639, but is caused by the intermediate interface. In the attached reproducer, Foo1 is the only case where S3971 is triggered.

Reproducer

class Foo1 : IAsyncLifetime
{
    public ValueTask DisposeAsync()
    {
        GC.SuppressFinalize(this); // <- S3971 complains here
        return ValueTask.CompletedTask;
    }

    public ValueTask InitializeAsync() => throw new NotImplementedException();
}

class Foo2 : IAsyncDisposable
{
    public ValueTask DisposeAsync()
    {
        GC.SuppressFinalize(this);
        return ValueTask.CompletedTask;
    }
}

class Foo3 : IDisposable
{
    public void Dispose()
    {
        GC.SuppressFinalize(this);
    }
}

Product and Version

SonarQube Server v2025.3.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions