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
There's no good way to promote a field #35525
Comments
Note, var _types = [int, String, bool];
var _i = 0;
class Foo {
Type get runtimeType {
_i = (_i + 1) % _types.length;
return _types[_i];
}
}
void main() {
var f = Foo();
print(f.runtimeType);
print(f.runtimeType);
} It would probably make sense to seal |
This would probably be the most concise way to write this today: class Bar<T, R, S> {
Bar(this.value);
final Object value;
void foo() {
var v = value;
if (v is Bar<T, R, S>) {
v.la(1);
v.la(2);
v.la(3);
}
}
void la(int x) { }
} Promoting the field directly is tricky as |
Dart currently cannot promote any field because there is no analysis ensuring that it's not mutated between test and use. (Personally, I like the idea of unsafe promotion: You check that some expression has type Rather than "sealing" the |
No, it isn't. Not without sealing (or mandatory whole program analysis). Because I can implement that final field in a subclass with a getter that returns a different value every time based on the time of the day. |
@Hixie Leaving aside the
|
The general pattern is:
Using
|
This is particularly painful and confusing with NNBD. I haven't done a lot of migration work yet, but so far this accounts for about half of the total new analysis errors I'm seeing, and almost all of the It may be worth noting that in all the cases I'm dealing with, the field in question is private, so local analysis (for top-level fields) or library-level analysis (for class fields) would show that there's no way the value changed between references. |
@nex3 are these all final as well? I ask because I'm interested in pushing on the local analysis approach and have some initial thoughts about how to approach this, but I think doing escape analysis to see if there's a possibility that a field is assigned is probably a non-starter. Would you give up the ability to Would you give up the ability to access these fields through a dynamic invocation? What about testing? Would you be ok not being able to mock these fields via a getter or NSM? Or would you need an unsound escape hatch for tests? |
|
Agree with @nex3 It is really painful to upgrade this kind statements for NNBD (with a local variable or other approaches). It can be error-prone if the code is complicated.
Worse of all, almost of zero of code will return null in the 2nd invocation (if setter is never called). It is kind of treating every citizen as criminal while the crime rate is almost negligible. Is it possible to introduce a keyword to mark a getter that can return a different value in different invocations? Otherwise, consider it is immutable before setter is called. Then, it will be much easier to upgrade to NNBD for us -- we got hundreds thousands of lines of code! For example,
|
A getter can always return a different value in different invocations. If we need anything, it's a marker to say that a getter cannot return a different value in a second invocation. It would have to be something you opt in to as an author, because will be a breaking change to remove that marker in a later change. It will still not help with getters which might change at some later time, but you just happen to know won't change between this test and the following use. I generally find that nullable fields are fairly likely to be mutable, and mutable fields can't be stable. |
(This bug assumes a world with
implicit-casts: false
.)If I have a class with a field of unknown type, there's currently no clean way to write the code that handles that field in a type-safe way, as far as I can tell.
What is the preferred way to write this code?
I've run into this in various places but most recently when writing a class to represent Json data.
The text was updated successfully, but these errors were encountered: