Add LDM notes for Feb. 25th, 2019

This commit is contained in:
Andy Gocke 2019-02-28 14:05:14 -08:00
parent afe6679f71
commit b83a527fbc
2 changed files with 94 additions and 4 deletions

View file

@ -0,0 +1,88 @@
# C# Language Design Notes for Feb 25th, 2019
## Agenda
Semantics of `base()` calls in default interface implementations and classes
## Discussion
The exact semantics of `base()` are still unresolved. Consider
the following legacy `base` call.
```C#
class A
{
virtual void M() {}
}
class B : A
{
// override void M() { }
}
class C : B
{
override void M() => base.M();
}
```
The behavior for `base` is to find the "nearest" implementation and call
that implementation using a direct call, meaning if B.M is uncommented it
will be called, while if it commented out then A.M will be called. Notably,
if `B` is uncommented at compile time, but at runtime the `B.M` override is
not present *the runtime will call A.M.* This is because the runtime will
continue looking through base classes for a matching signature if the target
method is not present.
Most importantly, the runtime *does not* yet have this behavior for `base()`
calls in interface implementations. This is because there could be multiple
paths to search down and the current IL encoding does not provide a root
definition to search towards.
For example,
```C#
interface IA
{
void M();
}
interface IB : IA
{
void IA.M() // If this gets removed, the IC.M call will fail
{
base(IA).M();
}
}
interface IC : IB
{
void IA.M() => base(IB).M();
}
```
At the moment, we do not have the time to implement an entire new IL form
for `base()` calls, so we have to implement a behavior in absence of that
feature.
Choices:
1. No `base()` call
2. `base()` call can only target the original definition of the method
3. `base(T).M()` call is a direct call to `T` and an error if the method
doesn't exist
4. `base(T)` starts searching in `T`, but in the compiler looks at the bases
for a unique, most derived implementation.
For feature evolution, we then have three more choices later.
1. Stay as-is
2. New opcode/behavior for `base()`
3. New opcode/behavior for `base.` and `base()`
**Conclusion**
For the first choice, let's do (3). The emitted code will be a direct call to
that method. It is expected that the runtime will throw an exception if an
implementation is not present in that type. For binding, in classes the
signature used will be the closest override, while for interfaces the
signature will be the member definition.

View file

@ -40,16 +40,18 @@
- Triage [#2152](https://github.com/dotnet/csharplang/issues/2152): "Allow Obsolete attribute on getters and setters"
- Open issues in recursive pattern-matching https://github.com/dotnet/csharplang/issues/2095
# C# Language Design Notes for 2019
Overview of meetings and agendas for 2019
## Feb 25, 2019
[C# Language Design Notes for Feb 20, 2019](LDM-2019-02-25.md)
- Open issues in default interface methods (https://github.com/dotnet/csharplang/issues/406).
- Base calls
- We currently have open issues around `protected`, `internal`, reabstraction, and `static` fields among others.
# C# Language Design Notes for 2019
Overview of meetings and agendas for 2019
## Feb 20, 2019
[C# Language Design Notes for Feb 20, 2019](LDM-2019-02-20.md)