csharplang/meetings/2017/LDM-2017-10-11.md
2017-12-05 17:06:17 -08:00

3.4 KiB

C# Language Design Notes for Oct 11, 2017

Warning: These are raw notes, and still need to be cleaned up. Read at your own peril!

Agenda

We looked at the design review feedback for nullable reference types.

Philosophy

Takeaways: Let unconstrained type parameters be its own special case; don't let it degrade the experience.

This is linting, make most existing code work, and don't shout at people too much.

Conclusion

agree, but let's consider a paranoid mode; "Xtreme". Could do that later.

Everybody who want the Xtreme mode would be happier with something than nothing. Should see what reaction is, and then dfecide whether to do it in-compiler, as analyzers or not at all.

Switches

Feedback: Don't have many switches. Just on or off.

Off would mean suppress the warnings. The syntax would still be allowed.

Conclusion

THis is a good philosophy. (We might allow Xtreme). We don't need to prototype the switch; it would always be on.

Dotted names

Feedback is we should track dotted names, and be very forgiving about what invalidates null state.

Invalidation: assigning to a prefix, or passing it by out or ref.

Conclusion

(Could go different with Xtreme mode)

Type narrowing

void M(string? n)
{
	if (n == null) return;
	var s = n; // string 
	var l = s.Length;
	n = null; // ok
	s = null; // ???
}

(Separate design discussion for IDE about what to show for n).

T[] MakeArray<T>(T v1, T v2)
{
	return new T[] { v1, v2 };
}

void M(string? n)
{
	if (n == null) return;
	var a = MakeArray(n, n); // string[] or string?[] ?
	var l = a[0].Length; // ???
}
T N<T>(ref T r, T t)
{
    
}

void M(string? n)
{
	if (n == null) return;
	var s = N(ref n, n); 
}

This one is interesting because even though n goes in as an lvalue, the method cannot legally assign a null to it.

Conclusion

We want to start treating the values of nullable variables with nonnull state as nonnullable in type inference.

Dammit operator type narrowing

T[] MakeArray<T>(T v)
{
	return new T[] { v };
}

void M(string? n)
{
	var a = MakeArray(n!); // string[] ?
	var l = a[0].Length; // ???
}

Null suppression:

List<string?> l = GetList()!; // returns List<string>

Conclusion

`! should keep its warning suppression, but also narrow the outermost type when it can, to match the new behavior when null-state is non-null.

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.

Dammit operator stickiness

Dammit operator lacks "stickiness" - you have to keep applying it (or introduce another local).

Idea is to maybe have some top-level "assertion" that would declare a thing not-null for the whole scope.

Other idea is to have s! influence null state for flow analysis, staying "valid" for as long as a non-null state would have.

string? s = ...

if (s != null && s.Length == 5) ... // It flows here
M((s!, s);                           // why not here?

It would sort of make s! mean the same as s = s!.

There are also cases where you wouldn't want it to be sticky, e.g. when you are using ! to shut a specific unannotated API that is lacking a ?.

Conclusion

We don't know what, if anything, to do here.

Array covariance

Conclusion

We'll think about this more.

Null warnings

Agree with feedback

Libraries