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

Warnings reported after comparing with object == or != #27928

Closed
cston opened this issue Jun 15, 2018 · 7 comments
Closed

Warnings reported after comparing with object == or != #27928

cston opened this issue Jun 15, 2018 · 7 comments

Comments

@cston
Copy link
Member

cston commented Jun 15, 2018

Warnings are reported for the second and third cases:

class C
{
    static void F(object? x, object y)
    {
        if (x != null) x.ToString();
        if ((object)x != null) x.ToString(); // warning
        if (x == y) x.ToString();            // warning
    }
}

[jcouv update:] Besides object equality, we should also consider other types (using attribute annotations).

@sharwell
Copy link
Member

sharwell commented Jun 16, 2018

Why would the second line not be desired? I would expect the following to be the solution there:

-if ((object)x != null) x.ToString(); // warning
+if ((object?)x != null) x.ToString();

@cston
Copy link
Member Author

cston commented Jun 18, 2018

@sharwell explicit cast should not remove top-level nullability so the inferred state of (object)x is object?.

@jcouv
Copy link
Member

jcouv commented Aug 8, 2018

I think the first scenario ((object)x != null) was fixed.
@cston @333fred What do you think about the second scenario (x == y informing null-state)?

class C
{
    static void F(object? x, object y)
    {
        if (x != null) x.ToString();
        if ((object)x != null) x.ToString(); // no warning
        if (x == y) x.ToString();            // warning
    }
}

sharplab

Update:
To handle this properly, we should probably analyze custom operators (they may not allow for this inference), but recognize operator==(object, object) specially or annotate it with a special attribute.

@333fred
Copy link
Member

333fred commented Aug 8, 2018

My first instinct is that it should inform nullability, and I suspect that it will be most of our users first instinct as well.

@jcouv
Copy link
Member

jcouv commented Mar 10, 2019

I'm not sure that we can learn from the x == y test.
Should we learn that x is non-null, or that y may be null? Both use cases seem plausible.
Maybe defensive checks for y == null should have been placed before checks for x == y, but that seems a strong assumption to make.

static void F(object? x, object y)
{
    if (x == y) x.ToString(); // warning is correct
    if (y == null) y = "";
}

@sharwell
Copy link
Member

sharwell commented Mar 10, 2019

@sharwell explicit cast should not remove top-level nullability so the inferred state of (object)x is object?.

I find this unintuitive in the context of the current issue. Do you have a link to explanation of cases where this behavior is expected to produce behavior users are expecting?

@jcouv
Copy link
Member

jcouv commented Mar 14, 2019

@sharwell I'll try to reconstruct the rationale supporting the current behavior of cast. I just remember it was to help with migrating existing code.

A few options:

  1. current: (string) cast passes top-level nullability through, W-warns on maybe-null input
  2. alternative: (string) cast produces a non-null value, and therefore should produce a safety warning on maybe-null input (otherwise we're decreasing safety)

I don't recall whether there are other options that are sensible. But between those two, (1) is preferable because it allows someone to migrate existing code with the safeonlywarning option (ie. no W-warning) with minimal annoyance if their code was correct/safe.

I'll go ahead and close this issue, as we've implemented the specified behavior.

@jcouv jcouv closed this as completed Mar 14, 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

6 participants