Skip to content

Commit f4fe0f1

Browse files
authored
Address issue #1246 (#1258)
Adds `notnull` as a contextual keyword and defines how the ambiguity with *class_type* is resolved. Co-authored-by: Nigel-Ecma <[email protected]>
1 parent 3339c44 commit f4fe0f1

File tree

2 files changed

+10
-8
lines changed

2 files changed

+10
-8
lines changed

standard/classes.md

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -493,14 +493,16 @@ For a type parameter `T` when the type argument is a nullable reference type `C?
493493
494494
The ***not null*** constraint specifies that a type argument used for the type parameter should be a non-nullable value type or a non-nullable reference type. A type argument that isnt a non-nullable value type or a non-nullable reference type is allowed, but a compiler may produce a diagnostic warning.
495495
496+
Because `notnull` is not a keyword, in *primary_constraint* the not null constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `notnull` succeeds it is treated as a `class_type`. Otherwise it is treated as the not null constraint.
497+
496498
The value type constraint specifies that a type argument used for the type parameter shall be a non-nullable value type. All non-nullable struct types, enum types, and type parameters having the value type constraint satisfy this constraint. Note that although classified as a value type, a nullable value type ([§8.3.12](types.md#8312-nullable-value-types)) does not satisfy the value type constraint. A type parameter having the value type constraint shall not also have the *constructor_constraint*, although it may be used as a type argument for another type parameter with a *constructor_constraint*.
497499
498500
> *Note*: The `System.Nullable<T>` type specifies the non-nullable value type constraint for `T`. Thus, recursively constructed types of the forms `T??` and `Nullable<Nullable<T>>` are prohibited. *end note*
499501
500-
Because `unmanaged` is not a keyword, in *primary_constraint* the unmanaged constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `unmanaged` succeeds it is treated as a `class_type`. Otherwise it is treated as the unmanaged constraint.
501-
502502
The unmanaged type constraint specifies that a type argument used for the type parameter shall be a non-nullable unmanaged type ([§8.8](types.md#88-unmanaged-types)).
503503
504+
Because `unmanaged` is not a keyword, in *primary_constraint* the unmanaged constraint is always syntactically ambiguous with *class_type*. For compatibility reasons, if a name lookup ([§12.8.4](expressions.md#1284-simple-names)) of the name `unmanaged` succeeds it is treated as a `class_type`. Otherwise it is treated as the unmanaged constraint.
505+
504506
Pointer types are never allowed to be type arguments, and dont satisfy any type constraints, even unmanaged, despite being unmanaged types.
505507
506508
If a constraint is a class type, an interface type, or a type parameter, that type specifies a minimalbase typethat every type argument used for that type parameter shall support. Whenever a constructed type or generic method is used, the type argument is checked against the constraints on the type parameter at compile-time. The type argument supplied shall satisfy the conditions described in [§8.4.5](types.md#845-satisfying-constraints).

standard/lexical-structure.md

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -591,12 +591,12 @@ A ***contextual keyword*** is an identifier-like sequence of characters that has
591591

592592
```ANTLR
593593
contextual_keyword
594-
: 'add' | 'alias' | 'ascending' | 'async' | 'await'
595-
| 'by' | 'descending' | 'dynamic' | 'equals' | 'from'
596-
| 'get' | 'global' | 'group' | 'into' | 'join'
597-
| 'let' | 'nameof' | 'on' | 'orderby' | 'partial'
598-
| 'remove' | 'select' | 'set' | 'unmanaged' | 'value'
599-
| 'var' | 'when' | 'where' | 'yield'
594+
: 'add' | 'alias' | 'ascending' | 'async' | 'await'
595+
| 'by' | 'descending' | 'dynamic' | 'equals' | 'from'
596+
| 'get' | 'global' | 'group' | 'into' | 'join'
597+
| 'let' | 'nameof' | 'notnull' | 'on' | 'orderby'
598+
| 'partial' | 'remove' | 'select' | 'set' | 'unmanaged'
599+
| 'value' | 'var' | 'when' | 'where' | 'yield'
600600
;
601601
```
602602

0 commit comments

Comments
 (0)