117 lines
No EOL
4.2 KiB
Markdown
117 lines
No EOL
4.2 KiB
Markdown
|
|
# C# Language Design Notes for Oct 29, 2018
|
|
|
|
## Agenda
|
|
|
|
[Source-level opt-in to nullable reference types](https://github.com/dotnet/csharplang/issues/1939)
|
|
|
|
## Discussion
|
|
|
|
### Philosophy of specification
|
|
|
|
To start off we discussed the proposal in the broader context of specifying
|
|
nullability as a feature in the language specification. The proposal talks
|
|
about "nullable contexts" but we also need to decide what a "context" implies.
|
|
|
|
Two basic approaches:
|
|
|
|
1. Specify all the details in the language spec, including annotations.
|
|
2. Specify very loosely: "'?' means the programmer expects the value may be
|
|
null. The absence means the programmer does not expect the value to be null."
|
|
|
|
Where we land on this spectrum decides how prescriptive we need to be about
|
|
the warnings produced and exactly what conditions produce them.
|
|
|
|
First question: how much does the spec act as the intermediary of conforming
|
|
compiler implementations? One argument is that warnings are not decisions
|
|
about legal programs, so the requirements are softer than other areas of the
|
|
spec. On the other hand, warnings often make a big difference when trying to
|
|
port from one compiler to another, regardless of how much they matter to the
|
|
spec. In the past, presence of warnings has been a major factor in porting
|
|
from `msc` to `csc` and vice versa.
|
|
|
|
However, the Roslyn analyzer public API could be seen as part of the warning
|
|
surface which is entirely at the compiler level, and creates far more burden
|
|
on other C# compiler implementations than any spec addition.
|
|
|
|
An elaboration of (2) is that we could think about the entire feature, aside
|
|
from the new syntax for `?` and `!` as a "built-in analyzer" for the compiler
|
|
that isn't strictly specified by the language, but also therefore cannot
|
|
affect the semantics of the language.
|
|
|
|
**Conclusion**
|
|
|
|
We're actually going to end up somewhere in a spectrum between (1) and (2),
|
|
but we're interested in leaning more towards (2).
|
|
|
|
### Annotation vs Warning context
|
|
|
|
*Q: Do we want to provide warnings about `?` when the annotation context is
|
|
*disabled?*
|
|
|
|
Similarly, do we want to emit metadata that treats these as nullable types
|
|
to users of the library?
|
|
|
|
If we don't warn, this would allow you to easily add `?` for use in other
|
|
areas of the code where the context is enabled, letting you easily annotate
|
|
your code over time.
|
|
|
|
On the other hand, there's no way to go the other direction, indicating that
|
|
parameters are non-nullable and that nullable types should not be passed.
|
|
|
|
The original motivation was about a new user using the feature and you annotate
|
|
one parameter of your method:
|
|
|
|
```C#
|
|
void M(string arg1, string? arg2)
|
|
```
|
|
|
|
Without a pragma setting the non-null context, `arg1` is oblivious, but `arg2`
|
|
is nullable. The user may not realize that `arg1` is not non-nullable because
|
|
they don't have a pragma. The warning is a feedback system to let a user know
|
|
that they only part of the nullable feature enabled.
|
|
|
|
**Conclusion**
|
|
|
|
Warn about `?` when annotation context is off. Regardless of the annotation
|
|
context, the type is considered nullable and will generate warnings if used
|
|
by a consumer in a warning-enabled context. Similarly, metadata will persist
|
|
the nullable type and the consumer will consider the type nullable.
|
|
|
|
*Q: Do we warn on `!` when the warning context is off?*
|
|
|
|
First item -- even with the proposal, it's not clear what it means for a warning
|
|
context to be on or off. Does disabling the warning mean that the warning context
|
|
is off?
|
|
|
|
**Conclusion**
|
|
|
|
Don't warn about `!`, regardless of context.
|
|
|
|
### Scenarios
|
|
|
|
There's some argument that (5) and (6) may be more important/common than (3)
|
|
and (4), but that doesn't mean the conclusions change.
|
|
|
|
**Conclusions**
|
|
|
|
We like the `#nullable ...` directive, but we're not sure about the
|
|
`#pragma warning nullable ...`. Let's keep it for now, but we're not settled on
|
|
a specific definition.
|
|
|
|
Note: the proposal has the current syntax wrong. The proposal lists the syntax
|
|
for configuring a diagnostic as
|
|
|
|
```C#
|
|
#pragma warning CS4321 restore
|
|
```
|
|
|
|
but it is actually
|
|
|
|
```C#
|
|
#pragma warning restore CS4321
|
|
```
|
|
|
|
This was not intentional and the proposal should not be read as flipping the
|
|
ID order. In the proposal, `nullable` is meant to stand in for the diagnostic
|
|
identifier, effectively acting as a reserved diagnostic ID. |