In this meeting we looked at the proposal for nullable reference types in [nullable-reference-types.md](https://github.com/dotnet/csharplang/tree/7981ea1fb4d89571fd41e3b75f7c9f7fc178e837/proposals/nullable-reference-types.md).
Should this be part of a general annotations framework? Do we want to keep doing this specifically per feature or have a general framework for it? Maybe. Let's keep that in the back of our minds. We don't want to be blocked by figuring that out right now.
It would sort of break with a principle that nullability stuff has no runtime semantics, and also impose runtime cost (though that can be eliminated by a smart compiler, when the next thing that follows - e.g. dereferencing - also already starts with a null check).
On the other hand it might be good to verify non-nullness right then and there, rather than experience random fallout later. Is it an "I know what I'm doing" or a "check that I know what I'm doing" operator?
Is it really that useful to have nested nullability annotations, as in `string?[]` or `List<string?>`? On arrays you almost always have null elements. We suspect that it *is* useful, and would detract from the combo with generics if not there, but on the other hand it is a great simplification to only track nullability at the top level.
One problem with nested nullability is that casts will not be able to check the nullability of type arguments. A cast cannot distinguish `(List<string>)o` from `(List<string?>)o`, since the runtime object in `o` won't know if it was instantiated with `string` or `string?`. So the notion that "all is good after a successful cast" is lost.
If we *do* allow nullable type parameters, should you be able to say `!` on type parameters that may be nullable?
For generics we should find a few samples that we believe are representative, and focus on them. May be able to reuse ones from the Midori project.
It's similar to tuples in that we have runtime types ornated with extra compile time information. That's a good analogy for a check list, but we should feel free to reach different conclusions.
We need to decide *when* to check during a constructor. It could be before calling helpers on the instance (since they may assume non-nullability) or only at the end. Usefulness vs guarantee!
Should we disallow/discourage arrays of non-null, to try to avoid the array hole where you have an array of a non-nullable element type, initialized entirely with nulls?
Are this set of warnings part of the language, or are they a "compiler feature" - essentially some built-in analyzers. In the latter case we might allow them to evolve in a breaking way.
Not annotating locals would reduce the number of places that would need to be fixed when turning nullability on. They would then have their nullability inferred instead. It's a trade-off between expressiveness and upgrade burden. This goes to granularity of opt-in as well. It would cause a readability disconnect between locals and fields.
There's a proposal to allow `!` on parameter types `M(T! x)` to cause a runtime null check to be generated. That would be better written as `M(T x!)`, putting the `! on the parameter, since it's about the parameter itself, and would actually name the parameter in the exception thrown!
Also, it may work for dereferencing those values, but not so well if it is an argument: Does it influence overload resolution? What if there are many arguments?