-
Notifications
You must be signed in to change notification settings - Fork 4.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
Add NullableContextAttribute #36152
Add NullableContextAttribute #36152
Conversation
9e91a03
to
0b2f0d8
Compare
docs/features/nullable-metadata.md
Outdated
|
||
The first case, where all parts are oblivious in an oblivious context, matches the representation in legacy assemblies where there are no `NullaleAttribute` annotations. | ||
|
||
`NullableAttribute(1)` should be placed on a type parameter definition that has a `class!` constraint. |
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.
Consider adding an entry for notnull
#Closed
docs/features/nullable-metadata.md
Outdated
|
||
The first case, where all parts are oblivious in an oblivious context, matches the representation in legacy assemblies where there are no `NullaleAttribute` annotations. | ||
|
||
`NullableAttribute(1)` should be placed on a type parameter definition that has a `class!` constraint. |
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.
Are attributes in this list subject to NullableContextAttribute
optimizations? If yes, we might need to emit NullableAttribute(0)
within some contexts #Closed
docs/features/nullable-metadata.md
Outdated
|
||
`NullableAttribute(1)` should be placed on a type parameter definition that has a `class!` constraint. | ||
`NullableAttribute(2)` should be placed on a type parameter definition that has a `class?` constraint. | ||
`NullableAttribute(2)` should be placed on a type parameter definition that has no type constraints, `class`, `struct` and `unmanaged` constraints and |
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.
Consider adjusting this for notnull
#Closed
docs/features/nullable-metadata.md
Outdated
`NullableAttribute(1)` should be placed on a type parameter definition that has a `class!` constraint. | ||
`NullableAttribute(2)` should be placed on a type parameter definition that has a `class?` constraint. | ||
`NullableAttribute(2)` should be placed on a type parameter definition that has no type constraints, `class`, `struct` and `unmanaged` constraints and | ||
is declared in a context where nullable type annotations are allowed, that is eqivalent to having an `object?` constraint. |
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.
Typo "eqivalent". #Closed
docs/features/nullable-metadata.md
Outdated
namespace System.Runtime.CompilerServices | ||
{ | ||
[System.AttributeUsage( | ||
AttributeTargets.Assembly | |
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.
Should be replaced with a Module target instead #Closed
docs/features/nullable-metadata.md
Outdated
The attribute constructor takes a `bool enabled` argument: | ||
if `true`, reference types are interpreted as not nullable; | ||
if `false`, reference types are interpreted as oblivious. | ||
If there is no `NullableContextAttribute` on the containing member or containing types or assembly, |
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.
module vs. assembly #Closed
docs/features/nullable-metadata.md
Outdated
|
||
The attribute is not inherited. | ||
|
||
The C#8 compiler will recognize `NullableContextAttribute` instances on the assembly, types (top-level and nested types), |
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.
module vs. assembly #Closed
docs/features/nullable-metadata.md
Outdated
|
||
The C#8 compiler will recognize `NullableContextAttribute` instances on the assembly, types (top-level and nested types), | ||
and members. | ||
`NullableContextAttribute` will be ignored on other targets. |
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.
Is including other targets as valid in attribute definition safe? I think it is better to disallow the attributes on targets that we do not plan to recognize. #Closed
docs/features/nullable-metadata.md
Outdated
The C#8 compiler will recognize `NullableContextAttribute` instances on the assembly, types (top-level and nested types), | ||
and members. | ||
`NullableContextAttribute` will be ignored on other targets. | ||
Other forms of `NullableContextAttribute` on the expected targets will be treated as `NullableContext(false)`. |
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.
What other forms? #Closed
docs/features/nullable-metadata.md
Outdated
|
||
The C#8 compiler will emit `NullableContextAttribute(true)` on top-level types | ||
that contain any members (including members of nested types) with reference types that are not oblivious. | ||
No other `NullableContextAttribute` instances will be emitted on types or members, |
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.
If we don't emit it on nested types, it would be hard to test that we properly recognize the attribute on a nested type in metadata. #Closed
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.
Same goes for other forms of the attribute. #Closed
docs/features/nullable-metadata.md
Outdated
The C#8 compiler will emit `NullableContextAttribute(true)` on top-level types | ||
that contain any members (including members of nested types) with reference types that are not oblivious. | ||
No other `NullableContextAttribute` instances will be emitted on types or members, | ||
and no assembly-level attribute will be emitted. |
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.
module vs. assembly #Closed
|
||
```c# | ||
// C# representation of metadata | ||
[Nullable(2)] |
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 might want to preserve the examples, perhaps move them to the other file. #Closed
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.
docs/features/nullable-metadata.md
Outdated
The following `NullableAttribute` cases are recognized and emitted for type parameter definitions: | ||
1. `notnull` constraint in oblivious [emit context](#NullableContextAttribute): `NullableAttribute(1)` | ||
2. `class` constraint in `#nullable enable` and in oblivious [emit context](#NullableContextAttribute): `NullableAttribute(1)` | ||
2. `class` constraint in `#nullable disable` and in not annotated [emit context](#NullableContextAttribute): `NullableAttribute(0)` |
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.
- [](start = 0, length = 2)
Duplicate number #Closed
docs/features/nullable-metadata.md
Outdated
2. `class` constraint in `#nullable enable` and in oblivious [emit context](#NullableContextAttribute): `NullableAttribute(1)` | ||
2. `class` constraint in `#nullable disable` and in not annotated [emit context](#NullableContextAttribute): `NullableAttribute(0)` | ||
3. `class?` constraint: `NullableAttribute(2)` | ||
4. No `notnull`, `class`, `struct`, `unmanaged`, or type constraints in `#nullable enable` (the equivalent of an `object?` constraint): `NullableAttribute(2)` |
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.
In 'not annotated' context:
notnull
- No attribute
No constraints in #nullable enable
- NullableAttribute(2)
No constraints in #nullable disable
- If we do not emit anything, how do we distinguish this case from notnull
?
It might be good to enumerate all scenarios per NullableContextAttribute (rather than having items corresponding to different contexts in one list) to make sure there is no conflict/ambiguity.
#Closed
docs/features/nullable-metadata.md
Outdated
```C# | ||
[Nullable(2)] string s; // string? | ||
[Nullable({ 2, 1, 2 }] Dictionary<string, object> d; // Dictionary<string!, object?>? | ||
[Nullable({ 2, 1 }] int[] a; // int[]? |
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.
[Nullable({ 2, 1 }] [](start = 0, length = 19)
I think today we emit [Nullable({ 2, 0 }]
. Are you proposing a change? #Closed
docs/features/nullable-metadata.md
Outdated
[Nullable(2)] string s; // string? | ||
[Nullable({ 2, 1, 2 }] Dictionary<string, object> d; // Dictionary<string!, object?>? | ||
[Nullable({ 2, 1 }] int[] a; // int[]? | ||
[Nullable(1)] int[] b; // int[]! |
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.
I think today we emit [Nullable({ 1, 0 }]. Are you proposing a change? #Closed
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.
In a NullableContext(true)
emit context, we should use 1 for value types.
In reply to: 290513550 [](ancestors = 290513550)
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.
In a NullableContext(true) emit context, we should use 1 for value types.
Why do we need to emit any attribute for this type in NullableContext(true)
?
In reply to: 290519517 [](ancestors = 290519517,290513550)
docs/features/nullable-metadata.md
Outdated
[Nullable({ 2, 1, 2 }] Dictionary<string, object> d; // Dictionary<string!, object?>? | ||
[Nullable({ 2, 1 }] int[] a; // int[]? | ||
[Nullable(1)] int[] b; // int[]! | ||
[Nullable(0)] int[] c; // int[]~ |
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.
I think today we do not emit an attribute. Are you proposing a change? #Closed
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 will need to emit an attribute in a NullableContext(true)
emit context.
In reply to: 290513682 [](ancestors = 290513682)
docs/features/nullable-metadata.md
Outdated
The attribute constructor takes a `bool enabled` argument: | ||
if `true`, reference types are interpreted as not nullable; | ||
if `false`, reference types are interpreted as oblivious. | ||
If there is no `NullableContextAttribute` on containing types or the module, unannotated reference types are interpreted as oblivious. |
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.
unannotated [](start = 77, length = 11)
Does this refer to the absence of the NullableAttribute? #Closed
docs/features/nullable-metadata.md
Outdated
The C#8 compiler will recognize `NullableContextAttribute(bool)` instances on the module and (top-level and nested) types. | ||
The only valid targets for `NullableContextAttribute` are module and type - attributes on other targets will be ignored silently. | ||
|
||
The C#8 compiler will not emit a module-level `NullableContextAttribute`. |
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.
Are users allowed to apply the attribute in source? On any level. #Closed
|
||
Trivial/optimized cases: | ||
1) All parts are NotAnnotated – a NullableAttribute with a single value 1 (rather than an array of 1s) | ||
1) All parts are NotAnnotated � a NullableAttribute with a single value 1 (rather than an array of 1s) |
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.
� [](start = 30, length = 1)
Is this an intentional change? #Closed
2) All parts are Annotated - a NullableAttribute with a single value 2 (rather than an array of 2s) | ||
3) All parts are Oblivious – the attribute is omitted, this matches how we interpret the lack of an attribute in legacy assemblies. | ||
3) All parts are Oblivious � the attribute is omitted, this matches how we interpret the lack of an attribute in legacy assemblies. |
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.
� [](start = 27, length = 1)
Is this an intentional change? #Closed
docs/features/nullable-metadata.md
Outdated
1. No constraints (see below) in `#nullable disable`: `NullableAttribute(0)` | ||
1. No constraints (see below) in `#nullable enable`: `NullableAttribute(2)` | ||
|
||
"No constraints" (see above) means no `notnull`, `class`, `struct`, `unmanaged`, or type constraints - the equivalent of an `object?` constraint. |
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.
the equivalent of an
object?
constraint. [](start = 103, length = 42)
When #nullable enable
? #Closed
docs/features/nullable-metadata.md
Outdated
} | ||
class B | ||
{ | ||
[Nullable({ 2, 1 }] int[] a; // int[]? |
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.
[Nullable({ 2, 1 }] int[] a; // int[]? [](start = 3, length = 38)
I think today we emit [Nullable({ 2, 0 }]. Are you proposing a change? #Closed
docs/features/nullable-metadata.md
Outdated
class B | ||
{ | ||
[Nullable({ 2, 1 }] int[] a; // int[]? | ||
[Nullable(1)] int[] b; // int[]! |
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.
[Nullable(1)] int[] b; // int[]! [](start = 3, length = 38)
I think today we emit [Nullable({ 1, 0 }]. Are you proposing a change? #Closed
docs/features/nullable-metadata.md
Outdated
{ | ||
[Nullable({ 2, 1 }] int[] a; // int[]? | ||
int[] b; // int[]! | ||
[Nullable(0)] int[] c; // int[]~ |
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.
[Nullable(0)] int[] c; // int[]~ [](start = 3, length = 38)
For consistency with C.a
I would expect to see [Nullable({ 0, 1 }]
here. Unless you are proposing to make encoding for value types dependent on flags for other constituent parts within the same type reference. Please clarify. #Closed
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.
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.
LGTM (iteration 24), modulo suspicious visit for property parameters in NullableAttributesVisitor
This reverts commit f886470.
This reverts commit f886470.
Emit a
NullableContextAttribute
at each type and method where thebyte
value is the most commonNullableAttribute
(andNullableContextAttribute
) value within that scope. The redundantNullableAttribute
(andNullableContextAttribute
) attributes within the scope are dropped.This is the third part of three changes to address #35888.