-
Notifications
You must be signed in to change notification settings - Fork 1k
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
Create spec for const expressions for is patterns #7589
base: main
Are you sure you want to change the base?
Changes from 2 commits
ffb40d0
d5e4d8b
2767290
438900c
d66f305
1890653
259d137
9234d41
b065e8a
9eee89d
f8d2b7a
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -59,14 +59,14 @@ The [§12.23 section](https://github.com/dotnet/csharpstandard/blob/standard-v7/ | |
> - sizeof expressions, provided the unmanaged-type is one of the types specified in §23.6.9 for which sizeof returns a constant value. | ||
> - Default value expressions, provided the type is one of the types listed above. | ||
> - **`is` expressions with only the following subpatterns:** | ||
> - **Boolean literal patterns.** | ||
> - **Numeric literal patterns.** | ||
> - **Character literal patterns.** | ||
> - **String literal patterns.** | ||
> - **Relative numeric literal patterns.** | ||
> - **Relative character literal patterns.** | ||
> - **Null literal patterns.** | ||
> - **Default literal patterns.** | ||
> - **Boolean patterns.** | ||
> - **Numeric patterns.** | ||
> - **Character patterns.** | ||
> - **String patterns.** | ||
> - **Relative numeric patterns.** | ||
> - **Relative character patterns.** | ||
> - **Null patterns.** | ||
> - **Default patterns.** | ||
> - **And, or and not patterns.** | ||
> - **Parenthesized patterns.** | ||
> - **References to constant fields or locals inside constant patterns.** | ||
|
@@ -111,9 +111,54 @@ const bool z = d is not null; // always true | |
const bool p = b is null; // always false | ||
``` | ||
|
||
All the above are currently valid pattern matching expressions, that also emit warnings about their constant evaluation results, about them being always true or false. | ||
### Diagnostics | ||
|
||
When assigning those expressions to a constant symbol, these warnings about the constant result of the expression will **not** be reported, as the user intends to capture the constant value of the expression. | ||
All the above are currently valid pattern matching expressions, that also emit warnings about their constant evaluation results, being always true or false. | ||
|
||
When assigning those expressions in a constant context, these warnings about the constant result of the expression will **not** be reported, as the user intends to capture the constant value of the expression. Constant context involves: | ||
- initializers for const symbols (fields or locals) | ||
- attribute arguments | ||
- parameter default value | ||
- switch statement case labels | ||
- switch expression arms | ||
|
||
Examples for the above: | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's add some more examples. All of the examples here are always true, we want some always false as well. Let's also throw in some switch expression examples with proposed behavior; I don't want to go through the whole specification of switch expressions yet, but we can at least include some examples to demonstrate warning behavior for unreachable arms/locations where the arms don't cover the whole input range (ie, when you cover case 1 and 2, but not 3-uint.MaxValue). |
||
```csharp | ||
const int a = 4; | ||
const bool b = false; | ||
const long c = 4; | ||
const string d = "hello"; | ||
const Sign e = Sign.Negative; | ||
|
||
// local or field | ||
const bool x = a is default(int); // always false, no warning/error | ||
|
||
// attribute argument | ||
[assembly: Something(a is 4)] // always true, no warning/error | ||
|
||
// parameter default value | ||
// always true, no warning/error | ||
int Negate(int value, bool negate = e is Sign.Negative) { } | ||
|
||
// switch statement case label | ||
switch (b) | ||
{ | ||
// always true, no warning/error | ||
case a is c: | ||
break; | ||
} | ||
|
||
// switch expression arm | ||
var p = b switch | ||
{ | ||
// always true, no warning/error | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. 2 problems with this:
|
||
a is c => 1, | ||
}; | ||
``` | ||
|
||
**NOTE**: we do not introduce any breaking changes in the reported diagnostics. Currently, all the above cases are illegal reporting "CS0150: A constant value is expected". A warning about the values always evaluating to either true or false is also reported alongside the error. We remove the warnings from those places where `is` expressions are currently not permitted to be used due to the error. | ||
|
||
### Other patterns | ||
|
||
Pattern expressions containing non-constant subpatterns, like accessing properties, list patterns and var patterns, are **not** constant. In the below examples, all expressions will report compiler errors: | ||
|
||
|
@@ -143,3 +188,4 @@ Currently, equality and comparison operators can be used to compare against othe | |
[meetings]: #design-meetings | ||
|
||
- Approval for Any Time milestone: [Here](https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-10-09.md#is-expression-evaluating-const-expression-should-be-considered-constant) | ||
- November 27th, 2023 [Discussion](https://github.com/dotnet/csharplang/blob/main/meetings/2023/LDM-2023-11-27.md#making-patterns-constant-expressions) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We need to see the actual spec changes here. How do we have to redefine the sections that specify these constructs to introduce a constant context? What is the definition of a constant context itself?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Updated ptal