Add meeting notes for 2019-02-13

This commit is contained in:
Andy Gocke 2019-02-22 15:03:04 -08:00
parent 4e3f2e4ea5
commit 92d6ef6cc3
2 changed files with 184 additions and 4 deletions

View file

@ -0,0 +1,178 @@
# C# Language Design for February 13th, 2019
## Agenda
Nullable Reference Types: Open LDM Issues https://github.com/dotnet/csharplang/issues/2201
## Discussion
### Track assignments through `ref` with conditional expressions
What is the nullability of `ref` variables when assigned through conditional expressions?
```cs
string? x = "";
string? y = "";
(b ? ref x : ref y) = null;
x.ToString(); // warning?
y.ToString(); // warning?
```
```cs
string? x = null;
string? y = null;
(b ? ref x : ref y) = "";
```
One option is to assume nullability after a `ref` has been taken to a variable. However,
that would mean that a `ref` variable declared non-nullable could become nullable, which
seems too heavy-handed.
Similarly, disabling flow analysis for variables which are taken as the target of a `ref`
feels like violating our model, which is largely based on flow analysis.
Alias analysis, on the other hand, seems to complicated and any reliable implementation
would be too difficult for users to understand.
**Conclusion**
Let's reach a middle ground. Assignment between any two identifiers copies
the state and is then tracked separately. This is also true for `ref` locals.
So,
```C#
string? x = "";
string? y = "";
(b ? ref x : ref y) = null;
x.ToString(); // warning
y.ToString(); // warning
```
But the equivalent using `ref` locals does not.
```C#
string? x = "";
string? y = "";
if (b)
{
ref string? rx = ref x;
rx = null;
}
else
{
ref string? ry = ref y;
ry = null;
}
x.ToString(); // no warning
y.ToString(); // no warning
```
### Nullability of conditional access with unconstrained type parameters
What is the nullability of `x?.F()`?
```cs
class C<T, U>
where T : U
where U : C<T, U>?
{
static void M(U x)
{
U y = x?.F();
T z = x?.F();
}
T F() => throw null;
}
```
This question seems interesting even without the type parameters and also
contains a nested question about reachability.
Is the `null` case of `?.` reachable even if the expression is non-nullable?
And if it is, what is the null state of the LHS?
```C#
string x = "";
x?.ToString(); // warning?
```
**Conclusion**
The `null` case of `?.` is always reachable, meaning the result is always
maybe null e.g.,
```C#
var y = x?.M(); // y is maybe null here, if possible
```
Moreover, the LHS is considered maybe null in the null branch, so by normal
flow analysis, after the expression is evaluated a variable on the LHS will
be considered maybe null.
```C#
string x = "";
x?.ToString(); // warning that x is maybe null
```
### `!` operator on L-values
Where is `!` allowed?
* `M(out x!);` (note this also definitely assigns to `x` through the `!`)
* `M(out (x!));`
* `M(out (RefReturning()!));`
* `x! = y;`
* `M(out string x!);`
Current implementation is to allow in `out` scenarios, but disallow in assignment scenarios.
We dislike allowing it in regular assignment. We like allowing it in simple
`out` parameters. We're ambivalent on `M(out string x!)`, but it's
not easily representable in the syntax model and is very similar to the
related feature `parameter!`, with the opposite meaning.
**Conclusion**
Only allow `!` in simple `out` parameters with no declaration.
### `is` nullability in `false` case
See [dotnet/roslyn#30297](https://github.com/dotnet/roslyn/issues/30297)
```cs
string? s = null;
if (!(s is object)) { s.ToString(); /* could warn? */ }
if (!(s is string)) { s.ToString(); /* could warn? */ }
```
There are variants of this scenario with `string!` and `string~`. Should `is`
update the nullability in both branches or should the one branch be treated
as unreachable?
The problematic code is probably more like:
```C#
void M(string s)
{
if (s is IComparable t)
{
}
s.ToString(); // warning
}
```
Here the user may not have meant to do a null check, but gets the
side-effects of doing so anyway.
**Conclusion**
It seems important to respect a deliberate null check from the
user, even if the input variable is non-nullable. As a next step we
need to define exactly which tests we think are "deliberate" null
checks. For instance, `x is null` is certainly a null check, but
pattern matching may or may not be a *deliberate* null check, even
if the code contains a null check.

View file

@ -36,14 +36,16 @@
- Nullable Reference Types: Open LDM Issues https://github.com/dotnet/csharplang/issues/2201
## Feb 13, 2019
Nullable Reference Types: Open LDM Issues https://github.com/dotnet/csharplang/issues/2201
# C# Language Design Notes for 2019
Overview of meetings and agendas for 2019
## Feb 13, 2019
[C# Language Design Notes for Feb 13, 2019](LDM-2019-02-13.md)
- Nullable Reference Types: Open LDM Issues https://github.com/dotnet/csharplang/issues/2201
## Jan 23, 2019
[C# Language Design Notes for Jan 23, 2019](LDM-2019-01-23.md)