-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Representation variable of an extension type is not promoted #53446
Comments
@eernstg can you comment ? |
The specification does say that. I'll assume that it is only something like But we don't have For field-promotion (mk. 2), a representation object accessor is definitely stable, so it can safely be promoted and used as a receiver for field promotion, but only inside the declaring library. |
The specification doesn't spell out the details, but it has been part of the proposal for a long time that the representation variable can be promoted because it's stable (it cannot be overridden, and it is final). So the intention is that it should be promotable. However, it hasn't been spelled out in detail. Final private instance variables are currently (3.2) only promotable when they are accessed via So let's start with that: Promotion only occurs for a representation variable |
@johnniwinther @scheglov would it be easiest if I split this into an issue per front-end? |
Probably not. I suspect that promotion will be implemented in shared code. |
I think when @eernstg writes above:
I think he means that this is to be taken as part of the spec today, not a future plan as part of a separate language feature. |
We don't have such word as "stable" in the specification yet. But it seems reasonable to me that we say that What I don't understand, is the limitation "in the same library as the one that declares the extension type". |
Currently field promotion only applies to field declared inside the same library, for a number of reason. The main reason is that it makes a final field behave differently from a getter, and outside of the library, there should be no distinction. Whether a getter is written as a I want "extension type representation variable promotion" to also only apply inside the library where the extension type is declared. Whether an extension type getter is declared as by a So |
OK, now I understand, thank you. It is easy to restrict to a single library. We develop in Dart on the level of packages, not libraries. I know that the language does not tell anything about packages, but they are the fact of life. It seems natural to declare some extension types in one library, to be used in another library. |
This particular promotion could probably be allowed for an entire package. The other field promotions depend on knowing something about the entire program, which is different from knowing the entire package, since the package can contain more files than what are actually in the program. Or each program, when every test is its own program. |
Sorry, this kind of promotion isn't sound after all: extension type E(num n) {
void foo() {
if (n is int) {
e = E(1.5);
n.isEven;
}
}
}
E e = E(1);
void main() {
e.foo();
} The point is that assignment to a variable whose type is an extension type amounts to the same thing as assignment to the representation variable. So the representation variable may be considered to be final according to all usages inside the extension type (in particular, |
Assigning to an extension-typed variable should count as assigning to another receiver, in that it can change the value of all final variables accessed through that receiver. For: extension type E(num n) {
void foo() {
if (n is int) {
e = E(1.5);
n.isEven;
}
}
}
E e = E(1);
void main() {
e.foo();
} that code should work and be sound, even if we allow promotion of |
Ah, you're right, my thinking went off track! The value of (The representation variable, as well as OK, so we're back to square two: We were in the middle of a discussion about the promotion which is now (again ;-) known to be sound: In which situations do we allow it? I was proposing that we should adopt rules that are similar to the rules that we currently have for promotion of instance variables: Allow the promotion, but only in the same library. |
I created dart-lang/language#3342 in order to settle the question about promotability of representation variables. |
Implemented in the analyzer as 6968295. extension type A(num _it) {
void foo() {
if (_it is int) {
_it.isEven;
}
}
} The original code above does not work because it uses not private field as representation. |
The non-private field should work as well, I think. Since the getter is statically resolved, it's impossible for there to exist a non-stable override. (We really should allow promotion of all final static variables inside the same library too, not just private instance fields. @stereotype441) |
Promoting the representation variable in all cases (private or not) was part of an earlier version of the spec, and when the language team thought that was too aggressive I proposed that we should allow promotion of all representation variables in the same library. However, the language team only wanted to support promotion of representation variables with a private name, such that the rules are similar to the rules about promotion of instance variables. Here is a comment that I wrote on that same issue in order to summarize the discussion in the language team. The spec change (that is, the latest spec change about this topic) was made here. |
To bad. Good thing all my representation variables are named |
[Edit eernstg: See https://github.com/dart-lang/language/issues/3342 as well.]
According to the extension type specification representation variable is subject to promotion. But in the current implementation nor analyzer nor CFE don't promote it. For example, they both report errors below
A separate issue for private fields promotion #53439
Tested on the edge SDK (Sept 6, 2023) on Linux x64
The text was updated successfully, but these errors were encountered: