Feedback: We should view this as a linting tool. We have to make most existing code pass muster, and it's ok with a little more complexity and forgiveness in the rules to achieve that.
Feedback: Don't have many switches and levers. Just "on" or "off". "Off" would suppress the warnings, but the `?` syntax would still be allowed. Make the hard decisions once and for all at the language level, rather than leave people with too many options.
This is a good philosophy. We do think that there's possibly room for an "Xtreme" mode as well, for people that care more about catching more cases regardless of inconvenience.
Feedback: We should track dotted names, and be very forgiving about what invalidates the null state. Otherwise it violates the general philosophy and complains about too much existing code. Things that *would* invalidate non-null-ness of a dotted chain is assigning to (or maybe passing to an out or ref parameter) the variable itself or any mutable prefix.
Feedback: when a variable of a nullable reference type (e.g. `string?`) is known to not be null, we should consider its value to be of the narrower type `string`.
We previously abandoned this approach, because it doesn't work for e.g. type parameters, where we don't know if they are nullable reference types or not, and don't necessarily have an underlying non-nullable type to narrow *to*.
This is one of those places where we should forego simplicity for friendliness. We should adopt a hybrid approach: When a type is a known nullable reference type, then having a non-null state *should* narrow its type. When it is a type parameter that might be instantiated with nullable reference types, then we can't narrow it, and should just keep track of its null state.
There's hesitation because of the muddiness of using `!` for two different things. But we don't have a better idea. Explicit casts are quite verbose. We may need to revisit later, but for now, `!` suppresses warnings *and* de-nullifies the type when it can.
There are also cases where you *wouldn't* want it to be sticky, e.g. when you are using `!` to shut up a specific unannotated API that is lacking a `?`. Here you don't use `!` in the meaning of "this is really not null", but to the effect of "I am actually fine passing a null here". That meaning shouldn't really be contagious to subsequent lines.
Feedback: Fine to warn in most places where a null value is given a nonnullable type, but we should beware of a "sea of warnings" effect. Specifically, we shouldn't warn on array creation, as in `new string[10]`, even though it creates a whole array of undesired nulls, because it is so common in current code, and couldn't have been done "safely" before.