-
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
improve type promotion in strong mode #25565
Comments
Moved from dart-archive/dev_compiler#274. |
I'd like to propose that void fn(T v) {
// ...
}
void fnTakesObject(Object v) {
if (v != null && v is! T) return;
fn(v);
} This comes up when implementing collections, since they have a number of methods that take |
ah, good example. So right now that won't promote because of flow analysis (issue 3 above) but it'd be equivalent to this: void fnTakesObject(Object v) {
if (v == null || v is T) {
fn(v);
}
} Doing || generally would take union types, but we could definitely special case null, since that works for any T. |
To add to the list (unless this is being split into smaller issues?):
|
@srawlins ternary operators already work: class C {
var greeting = 'hello';
}
main() {
Object c = new C();
print(c is C ? c.greeting : 'world');
}
What you are likely seeing is one of the other problems above. With more info I can help you figure it out. |
Is this still happening? Will the analyzer and front_end both do the right thing? |
Maybe @leafpetersen knows where the language is heading on this? |
@bwilkerson Had a very nice proposal that covered a fair bit of this. It didn't make the cut for Dart 2 just because of time, but I hope we can find a good way to roll it out post 2. |
It looks like this is the canonical request for improved promotion, which is a topic that has been discussed for a long time (no proposal made it into Dart 2, but surely we'll get there at some point). I think it would be nice to use this issue as a focal point for that proposal. So here's a list of issues on this topic which contains the issues that I know about (you're welcome to extend the list if you know about a relevant issue that I overlooked):
Moreover, here's a PR that includes an overview of the ideas on the table at the given time:
|
@jmesserly, I've added a comment at the top of the original text of this issue and adjusted the labels to make this issue "the place to go" for discussions on promotion. I believe it does not fit so well as an 'area-analyzer' issue because the language design needs to be settled first, so I made it an 'area-language' issue; similarly, I removed 'analyzer-strong-mode' because it's now a Dart 2 effort (or 2.x, for some finite x), and the priority (because that priority was presumably concerned with the analyzer implementation). |
@eernstg -- that sounds perfect. Yeah feel free to edit my old description to whatever is most is helpful. It's great to have a canonical issue for type promotion work! |
Putting check marks on a couple of cases in the initial comment:
In current Dart, it is possible to promote a local variable whose type is
Also true today.
Today we have a rather complex flow analysis, and there are many ways in which the type of
We don't do that (because production code cannot be affected by
Kept this one active, the flow analysis basically doesn't try to keep track of which locations in the code are such that the function object definitely hasn't been invoked. So we're still disabling promotion a bit more than we'd like.
In current Dart we do this: There is a kind of type which is known as an intersection type (it's not a general intersection type, just a special case, and only a compile-time phenomenon). This kind of type supports a few special cases, presumably including the case about
Today there are lots of mutations of local variables which are compatible with promotion. We also have a notion of 'demotion' in the case where a promoted variable
I put a check mark here, too, because we can use This seems to indicate that only the part about function objects with potential side effects on local variables isn't yet covered. |
[Edit Sep 17 2018, eernstg: This seems to be the most generic issue on the topic of improving promotion, so I'd like to position it explicitly as "the place to go" for this discussion; I've added a comment listing other issues related to this topic here. I'll adjust the labels accordingly.]
There are some cases where type promotion won't work. Found while investigating the state of dart-archive/dev_compiler#31.
It roughly falls into a few buckets:
T
ofv
wasdynamic
, the testv is SomeType
won't promote. This leads to some suboptimal codegen in SDK (see strong mode should allow type promotion from dynamic #25486)S
is not a subtype ofT
, the test won't promote. You'd have to track a union type.if (v is! S) return;
don't affect the type ofv
in the rest of the method body.assert(v is S);
and havev
be treated as S for the rest of the method. Sort of like an unchecked (in production mode) cast, similar toS v2 = v
but not requiring a second variable name to be introduced.T extends Event
, not promoting to a subtype of Event likeInputEvent
, see Stack trace from editor evaluating code in CompileTimeConst visitor #327if (v == null || v is T)
, it should promote to nullable-TThe text was updated successfully, but these errors were encountered: