Skip to content

Warn for is-pattern using a relational pattern with a known result.#42501

Merged
gafter merged 9 commits intodotnet:features/patterns3from
gafter:patterns3-is-always-true-false
Mar 26, 2020
Merged

Warn for is-pattern using a relational pattern with a known result.#42501
gafter merged 9 commits intodotnet:features/patterns3from
gafter:patterns3-is-always-true-false

Conversation

@gafter
Copy link
Member

@gafter gafter commented Mar 17, 2020

Relates to #40727 (patterns for C# 9)

@gafter gafter added this to the Compiler.Net5 milestone Mar 17, 2020
@gafter gafter requested review from RikkiGibson and agocke March 17, 2020 17:48
@gafter gafter requested a review from a team as a code owner March 17, 2020 17:48
@gafter gafter self-assigned this Mar 17, 2020
@gafter gafter force-pushed the patterns3-is-always-true-false branch from 47db30f to 7d4d669 Compare March 20, 2020 18:02
@gafter
Copy link
Member Author

gafter commented Mar 20, 2020

@agocke @RikkiGibson Can you please review this small pattern-matching change?

else if (values?.Complement().IsEmpty != true)
{
tests.Add(new Tests.One(new BoundDagRelationalTest(rel.Syntax, rel.Relation, rel.ConstantValue, output, rel.HasErrors)));
}
Copy link
Contributor

@cston cston Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider wrapping block in if (fac is { }) { ... } to avoid multiple ?. operators and == true. #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I tried that, but ended up having to repeat line 625 in multiple else clauses.


In reply to: 395854215 [](ancestors = 395854215)

case BoundDagRelationalTest d:
var f = ValueSetFactory.ForSpecialType(input.Type.SpecialType);
if (f is null) return null;
// TODO: When ValueSetFactory has a method for comparing two values, use it.
Copy link
Contributor

@cston cston Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TODO [](start = 31, length = 4)

PROTOTYPE? #ByDesign

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The code works correctly as is. This is a suggestion for a future optimization, which I expect to happen after merging into master.


In reply to: 395854439 [](ancestors = 395854439)

Copy link
Member

@jcouv jcouv Mar 24, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be also filed as a follow-up issue? #Resolved

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That wouldn't be particularly helpful to me, though I don't object to it.


In reply to: 397252372 [](ancestors = 397252372)

}
";
CreateCompilation(source, options: TestOptions.ReleaseDll, parseOptions: TestOptions.RegularWithPatternCombinators).VerifyDiagnostics(
// (7,18): error CS8120: The switch case has already been handled by a previous case.
Copy link
Contributor

@cston cston Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error CS8120: The switch case has already been handled by a previous case. [](start = 31, length = 74)

This diagnostic message is confusing since there is no previous case. #Resolved

Copy link
Member Author

@gafter gafter Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what to do about this, as this is the message used (since C# 7.0) when a switch case is unreachable. What do you suggest? Give a different message if it is the first case? Reword it to be technically correct "Any value that would match this case has been handled by a previous case." ?


In reply to: 395883716 [](ancestors = 395883716)

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Or perhaps "Unreachable case. If there are values that satisfy this case, those values have been handled in previous cases."


In reply to: 395908208 [](ancestors = 395908208,395883716)

// (7,18): error CS8120: The switch case has already been handled by a previous case.
// case < int.MinValue: break; // 1
Diagnostic(ErrorCode.ERR_SwitchCaseSubsumed, "< int.MinValue").WithLocation(7, 18),
// (9,18): error CS8120: The switch case has already been handled by a previous case.
Copy link
Contributor

@cston cston Mar 20, 2020

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

error CS8120: The switch case has already been handled by a previous case. [](start = 31, length = 74)

This message is confusing since the previous cases do not handle this (out of range) case. #Resolved

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 4)

@jcouv jcouv self-assigned this Mar 24, 2020
@gafter
Copy link
Member Author

gafter commented Mar 24, 2020

@cston Do these error messages look better?

@gafter gafter closed this Mar 24, 2020
@gafter gafter reopened this Mar 24, 2020
@gafter
Copy link
Member Author

gafter commented Mar 25, 2020

@cston @jcouv @agocke @RikkiGibson Would you please have a look at the last iteration of this PR? It now gives warnings for more scenarios of always-true is-pattern expressions as requested at the feature design review yesterday.

// (6,29): error CS8521: Pattern-matching is not permitted for pointer types.
// bool M1(int* p) => p is null; // 1
Diagnostic(ErrorCode.ERR_PointerTypeInPatternMatching, "null").WithLocation(6, 29),
// (7,24): warning CS8794: An expression of type 'int*' always matches the provided pattern.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: should/could we try and avoid the cascade here? The error (not pattern-matching on pointer type) seems more fundamental

c.VerifyTypes();
c.VerifyDiagnostics(
// (6,13): warning CS8794: An expression of type 'object' always matches the provided pattern.
// if (x is var _)
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be added to the breaking changes document and thread.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 8), modulo documentation of breaking change (such as warning on var _)

@gafter
Copy link
Member Author

gafter commented Mar 25, 2020

@jcouv I removed the breaking change.

Copy link
Member

@jcouv jcouv left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM Thanks (iteration 9)

@gafter gafter merged commit 7fcd921 into dotnet:features/patterns3 Mar 26, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants