dart-lang / dart-lang/language
Make adding a private field not a breaking change
- Dominant language
- TeX
- Stars
- 2.9k
- Forks
- 239
- Avg merge
- 2d 18h
- Merged PRs (30d)
- 14
Description
Based on a discussion around the specification of interface resolution, @eernstg and I noted that currently as implemented adding a private field can be a breaking change. Example:
```dart
// test.dart
library A;
import 'test2.dart';
abstract class A {
_bar(int x);
_foo({int x});
}
abstract class B {
_bar(String x);
_foo([int x]);
}
void test(C x) {
x._foo(x : 3); // Legal?
x._foo(3); // Legal?
x._bar(3); // Legal?
x._bar("hello"); // Legal?
}
```
```dart
// test2.dart
library B;
import 'test.dart';
abstract class C implements A, B {}
```
Both implementations currently reject the definition of class `C`, which means that from the perspective of library `A`, adding the second of the two unrelated definitions of `_foo` could have broken code. Note that `_foo` is unsatisfiable, but a concrete implementation of `C` could provide a method implementing both versions of `_bar`.
There was a proposal to specify this such that `C` would be allowed, with the conflict resolution only occurring at the point where `_foo` was made concrete. However, it's not clear what the static checking for this should be, nor how to implement this. In particular, how do you generate code for the calls to `_foo` and `_bar` in the `test` method? How do you generate noSuchMethod forwarders for something implementing this interface externally? There are a lot of unanswered questions here. Some possibilities:
- Arbitrarily choose one of the versions of `_foo`/`_bar` as the "primary" one to do static checking against, but keep the others "around" and check that any concrete implementation satisfies all of them. Probably we would choose the first to occur in the lexical list of direct super-interfaces.
- So only one of the two calls to `_foo` or `_bar` in `test` would be statically accepted.
- Use name mangling to generate multiple entry points at the different type signatures, in addition to the the unmangled signature.
- So all of the calls to `_foo` and `_bar` would be accepted
- Code generation would have to deal with the name mangled signatures, not sure what the scope of this is
- This de facto adds a limited form of overloading through a backdoor, which seems non-ideal.
For now, we will keep the existing behavior of making `C` an error at declaration site.
cc @lrhn @eernstg @munificent
Contributor guide
Assessment
This issue has not been assessed yet.