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

Nullable inference not tracking Boolean logic correctly with Debug.Assert #34665

Closed
stephentoub opened this issue Apr 2, 2019 · 8 comments
Closed
Labels
Area-Compilers Feature - Nullable Reference Types Nullable Reference Types Resolution-By Design The behavior reported in the issue matches the current design

Comments

@stephentoub
Copy link
Member

stephentoub commented Apr 2, 2019

Version:
3.0.0-beta4-19170-01+1deafee3682da88bf07d1c18521a99f47446cee8

#nullable enable
using System;
using System.Diagnostics;

class Program
{
    static void Main() { }

    static void Foo(object? first, object? second)
    {
        Debug.Assert(first != null || second != null);

        if (first != null)
        {
            Console.WriteLine(first.GetHashCode());
        }
        else
        {
            Console.WriteLine(second.GetHashCode());
        }
    }
}

This warns on the last line that second might be null ("Possible dereference of a null reference"), but the compiler should be able to see that's not possible, given the Assert that at least one of first or second is non-null and then that first is null.

cc: @cston, @jaredpar, @dotnet/nullablefc

@stephentoub stephentoub changed the title Nullable inference not tracking Boolean logic correctly Nullable inference not tracking Boolean logic correctly with Debug.Assert Apr 2, 2019
@gafter gafter added the Resolution-By Design The behavior reported in the issue matches the current design label Apr 2, 2019
@gafter
Copy link
Member

gafter commented Apr 2, 2019

We do not track the relationship between multiple variables. The specified analysis says that the state of a variable is either known not to be null, or else that it might contain null. After the assertion, we have no further information of that sort to add to the pool of knowledge.

In short, while a human can deduce that there is no problem on the last line, and perhaps so could a sufficiently powerful theorem prover, we have specified a realistic analysis that cannot and does not do what you expect. And the compiler implements that specified analysis.

@gafter gafter closed this as completed Apr 2, 2019
@stephentoub
Copy link
Member Author

It sounds like you're saying a more powerful one is feasible but we've decided it's not worth it. Ok. Just means more !s I guess... what's a few more when you already have a lot :)

@gafter
Copy link
Member

gafter commented Apr 3, 2019

We've settled on our current approach as a sweet spot balancing moderate complexity of analysis (i.e. implementable in a reasonable time frame and with reasonable performance) and customer value. I don't believe we've explicitly discussed (or "decided" against) a theorem-prover style analysis, which is what would be needed. The reason we didn't discuss it is that there is no member of the LDM that believes it would be an improvement over our current approach.

@stephentoub
Copy link
Member Author

no member of the LDM that believes it would be an improvement over our current approach

Ok. It depends of course on how you define "an improvement". Fewer warnings due to more complete analysis seems like an improvement to me, but I get that it's a tradeoff.

@gafter
Copy link
Member

gafter commented Apr 3, 2019

@stephentoub you are a member of the LDM. Why don’t you propose that we drop our plans to release the nullable reference types feature in the C# 8 timeframe and spin up a team of engineers to develop a theorem-prover style analyzer for some indefinite future release?

@stephentoub
Copy link
Member Author

stephentoub commented Apr 3, 2019

Hyperbole isn't necessary here. I opened an issue to highlight cases that we're hitting not-infrequently while annotating corelib, in hopes of making the overall feature better, and I'm questioning statements that suggest it's not actually an issue that, if addressed, would make the situation better for our collective customers. I've also stated multiple times that I understand it's a tradeoff.

@gafter
Copy link
Member

gafter commented Apr 3, 2019

I agree my comment was unwarranted, and that there is customer value that our current approach doesn't address. We've looked at this sort of inference in passing in the context of contracts, but we've never gotten to the point that we think it is something we should do in the product. I'll open a language feature request corresponding to this product issue.

@stephentoub
Copy link
Member Author

stephentoub commented Apr 3, 2019

Thanks, Neal. Sounds good.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Area-Compilers Feature - Nullable Reference Types Nullable Reference Types Resolution-By Design The behavior reported in the issue matches the current design
Projects
None yet
Development

No branches or pull requests

3 participants