Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Consider special-casing Interlocked.Exchange and friends for nullable inference #51191

Open
stephentoub opened this issue Feb 12, 2021 · 1 comment

Comments

@stephentoub
Copy link
Member

Version Used:
2d3ffe0

Description
One semi-common pattern when using Interlocked.Exchange and friends when using it to rent some shared object is to first check whether the field is null to avoid the overhead of the interlocked operation if it's unlikely to succeed:

if (field is not null)
    ... = Interlocked.Exchange(ref field, null);

Because of that upfront null check, however, the C# compiler's nullable inference then infers the type of the field as being non-nullable rather than nullable, and thus warns that the null being used in the Exchange can't be converted to a non-null value. This is easily worked around by specifying the type parameter to Exchange explicitly, but it seems like we may want to special-case threading-focused APIs like Exchange to opt-out of this inference.

It's of course possible that'll lead to other warts, though, so if this is too niche, feel free to close.

Steps to Reproduce:

#nullable enable

using System;
using System.Threading;

public class C {
    private C? _obj;
    
    public void Rent()
    {
        if (_obj is not null)
        {
            C? o = Interlocked.Exchange(ref _obj, null);
            if (o is not null)
            {
                Use(o);
            }
        }
    }
    
    private void Use(C o) {}
}

https://sharplab.io/#v2:EYLgtghgzgLgpgJwD4GIB2BXANliwtwAEcaeBAsAFBUACATAIy0AMhNDAdACoAWCcEACYBLNAHMA3FVoBmNnUIBhQgG8qhDYQAOCYQDcI8JQH5CAfQD2wAFZTKmwus005NACyEASiRgAKAJROGmr2DprCAGaEvpY2hMJQhGgWMEnYWIGhYapB2ZqKphaEALyEAJJo8AhYFgDGANZwghwAogAetTwQ4nC+/FGx1gA0aTj+dnlhkdFFCUkpoxm5kyGTkwCqUL0W48t5AL57GodZhCcOuTr6hkTuhJu9yjuqJ/tAA==

Expected Behavior:
No warnings

Actual Behavior:
warning CS8625: Cannot convert null literal to non-nullable reference type.

cc: @jcouv

@dotnet-issue-labeler dotnet-issue-labeler bot added Area-Compilers untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 12, 2021
@jaredpar jaredpar added Bug Feature - Nullable Reference Types Nullable Reference Types and removed untriaged Issues and PRs which have not yet been triaged by a lead labels Feb 12, 2021
@jaredpar jaredpar added this to the C# 10 milestone Feb 12, 2021
@RikkiGibson
Copy link
Contributor

Root cause may be #43536. Not currently clear to me that there's a need to special case Interlocked.Exchange.

@jaredpar jaredpar modified the milestones: C# 10, 17.0 Jul 13, 2021
@jaredpar jaredpar modified the milestones: 17.0, 17.1 Aug 3, 2021
@jinujoseph jinujoseph modified the milestones: 17.1, 17.3 Apr 27, 2022
@jaredpar jaredpar modified the milestones: 17.3, Backlog Jun 30, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants