dart-lang / dart-lang/language

Make adding a private field not a breaking change

Open
#101 6 comments 0 reactions 0 assignees View on GitHub
request state-backlog
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

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.