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

Warn if a value is never or always null #22743

Closed
alrz opened this issue Oct 18, 2017 · 12 comments
Closed

Warn if a value is never or always null #22743

alrz opened this issue Oct 18, 2017 · 12 comments

Comments

@alrz
Copy link
Member

alrz commented Oct 18, 2017

Version Used: NullableReferenceTypes branch

Steps to Reproduce:

    public void M(string? o) {
        if (o == null) return;
        var x = o?.Length; //!
    }

Expected Behavior: warning: o is never null

Actual Behavior: no warnings

Relates to #25592

@alrz
Copy link
Member Author

alrz commented Oct 18, 2017

Ideally I'd expect three warnings:

  • Possible null
  • Always null
  • Never null

This is on-par with the other proposed analysis (possibly on the ide side) for "expression is always true/false" to detect more unreachable code. e.g.

ExpressionSyntax expr = null;
// ...
// no expr assignments
// ...
if (expr == null) // expression is always true
{} else {/* unreachable */}

PS: the two analyses do seem to belong to the same bucket, that is, the compiler already knows if expr is or is not null at that point, so it could warn that the comparison is redundant.

@jcouv
Copy link
Member

jcouv commented Oct 18, 2017

Tagging @cston

@jcouv
Copy link
Member

jcouv commented Oct 18, 2017

I suspect we won't want to do that because in many cases, the nullable analysis will be imperfect (a trade-off between safety and flooding with warnings). For example, consider if (a.b.c == null) return; M(a.b); var x = a.b.c?.Length;.
The compiler may take the lenient view that a.b.c is non-null, but M could have changed that.

@alrz
Copy link
Member Author

alrz commented Oct 18, 2017

@jcouv So in your example it's not proven that c is never null i.e it's "possibly null' (which may or may not produce warning depending on how much we want to be optimistic to avoid flooding). This analysis, on the other hand, would be very local and only triggered on definitive cases.

@alrz
Copy link
Member Author

alrz commented Oct 18, 2017

I want to add, a "possible null dereference" warning for a definitive null dereference is a lot less useful when it comes to offering a fix - they demand different fixes outright: you add a null check for the former, but the latter is most likely a bug in the logic, or at best a leftover from a recent change which might be misleading for the reader later on. All in all, I think it could be done along with "always true/false" warnings since they both are similar in terms of use cases.

@bkoelman
Copy link
Contributor

I see great value in the distinction between "possibly" and "certainly" warnings. For example, const field access and locals should be "certainly" while property access should be "possibly".

The distinction enables teams suppress the "possibly" warnings but require fixing the "certainly" cases.

@jcouv jcouv added this to the 16.0 milestone Nov 2, 2017
@alrz alrz changed the title Warn if a value is never null Warn if a value is never or always null Dec 20, 2017
@gafter
Copy link
Member

gafter commented Dec 6, 2018

I also see value in the "certainly" analysis. But it isn't something we're doing or have any plans to do at this time. In code like this

    public Result SomePublicApi(Argument a)
    {
        if (a == null)
            throw new ArgumentNullException("A");

we should not provide a diagnostic. It is normal and expected for public APIs to check incoming parameters to ensure they are not null at runtime, even though the parameter was declared not to be null. If we did it, a more precise analysis would permit us to give these diagnostics when we are "certain".

@alrz
Copy link
Member Author

alrz commented Dec 6, 2018

The "always/never null" state would only produced by (local) nullable analysis, Argument a is at best "maybe not null" even though it's not annotate as nullable, because we're not sure if any nullable analysis is done on the client code (or if so, it's possible that it's been suppressed)

@CyrusNajmabadi
Copy link
Member

Agree with @alrz. This could/should only be done for when we can guarantee non-nullness (basically local/constant analysis only). Anything that flowed in from anywhere else would have to be assumed to be potentially null.

@jaredpar jaredpar modified the milestones: 16.0, Backlog Dec 7, 2018
alrz referenced this issue in dotnet/csharplang Dec 13, 2018
@alrz
Copy link
Member Author

alrz commented Dec 14, 2018

Oh, and a "never null" warning would flag x!! usages. which seems to be sensible.

@jcouv
Copy link
Member

jcouv commented Dec 14, 2018

Queued those questions on LDM backlog, which means we'll probably discuss in January.

@gafter
Copy link
Member

gafter commented Feb 25, 2019

At LDM on 2019-02-20 we confirmed that we are not including these diagnostics as part of the nullable reference types feature (though we might introduce them later)

@gafter gafter closed this as completed Feb 25, 2019
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

8 participants