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

Use TypeUnification.CanUnify to do additional compile-time checking in GetIsOperatorConstantResult #26100

Closed
gafter opened this issue Apr 11, 2018 · 3 comments

Comments

@gafter
Copy link
Member

gafter commented Apr 11, 2018

Since the result of GetIsOperatorConstantResult is no longer merely a heuristic for the quality of warnings - it is used to determine when a pattern-matching operation is illegal (when it returns false) - it is worth improving it sooner rather than later, as it would be a hard breaking change when it is tightened.

One way to do this is hinted at in the code - use TypeUnification.CanUnify to see if the input type and the tested type can possibly be substituted to types that have an inheritance relationship.

We should get LDM guidance to see if it is worth it.

@gafter gafter added this to the 16.0 milestone Apr 11, 2018
@gafter gafter self-assigned this Apr 11, 2018
@gafter
Copy link
Member Author

gafter commented Apr 11, 2018

Cases this could help with are hinted at in the code:

                    // We could then go on to get more complicated. For example, 
                    //
                    // bool M6<X>(C<X> x) where X : struct { return x is C<string>; }
                    //
                    // We know that C<X> is never convertible to C<string> no matter what
                    // X is. Or:
                    //
                    // bool M7<T>(Dictionary<int, int> x) { return x is List<T>; }
                    //
                    // We know that no matter what T is, the conversion will never succeed.

These cases could be handled by using unification as a subroutine. We would have to be careful regarding variance.

@gafter
Copy link
Member Author

gafter commented Apr 11, 2018

Here is another example

struct S<T>
{
    void M(S<T> x)
    {
        if (x is int) { } // MISSING warning: the given expression is never of the provided ('int') type.
        if (x is int i) { } // MISSING error: the given expression is never of the provided ('int') type.
        if (x is 3) { } // MISSING error: the given expression is never of the provided ('int') type.
    }
}

@gafter
Copy link
Member Author

gafter commented Nov 12, 2018

We're not going to do this in VS 2016. Which means we probably will never do it.

@gafter gafter closed this as completed Nov 12, 2018
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

1 participant