csharplang/meetings/2018/LDM-2018-10-29.md
2018-11-13 15:51:01 -08:00

4.2 KiB

C# Language Design Notes for Oct 29, 2018

Agenda

Source-level opt-in to nullable reference types

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:

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

#pragma warning CS4321 restore

but it is actually

#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.