-
Notifications
You must be signed in to change notification settings - Fork 205
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
Should implicit downcasts promote in null safety mode? #1362
Comments
I worry about the type of a variable changing with no syntactic hint. That feels like something that can be very hard to debug. It's only for So, ... all in all, I'd prefer not to promote on implicit downcasts. You don't get anything for free with |
+1. This seems like it would lead to really surprising behavior to me. |
Ok, that sounds like enough of a consensus to me. I'll make sure that we have tests to lock in this behavior (since it kind of got implemented by accident), and then once those land I'll close this issue. |
I agree that we should be careful about invisible promotions. Given that I've been loudly worried about this specific issue, I can't help mentioning that we do have some situations where promotion takes place with no syntactic hint: import 'someoneElsesLibrary.dart'; // Exports `int foo()`.
void main() {
int? i;
i = foo();
i.isEven; // OK.
int? j = ...;
j!.toString();
j.isEven; // OK.
} Similarly, in a non-trivial function body where What's the most consistent approach? We could treat the success of an implicit downcast from void f(dynamic d) {
if (d is int) { ... }; // `int` now of interest.
g(d);
d.isEven('Wrong argument list shape'); // Do we want the error here? ..
d = h();
d.isEven('Again'); // .. considering that we do get it here?
}
void g(int i) {}
int h() => 0; It seems consistent to me if we basically use every opportunity to promote to a type of interest, even though these promotions will generally not have a syntactic marker. |
I think the examples here are significantly different from an implicit downcast. An assignment changes the value of a variable to something under your control. That's a reasonable place to also change the type to the type of the assigned value. The implicit downcast does not assign a new value, and it doesn't have an explicit cast to signify that something happens here. |
https://dart-review.googlesource.com/c/sdk/+/175902 tests the current behavior so that we won't change it by accident in the future |
I think the "best" kind of promotion we have is I actually think that we would help developers by making it more strict, e.g., by pointing out explicitly that promotion failed at a specific type test or type cast, as soon as there is a compile-time error that would not have occurred in case the promotion had taken place. We could also warn at In contrast, many (surely most) assignments do not promote, and promoting assignments are implicit in other ways as well: Assignments don't make the target type visible, and the target type may change arbitrarily on We have previously made the choice (a good choice, I think) to limit the applicability of implicit promotions, such that they can only promote to a type of interest, that is, a type which has actually been mentioned nearby, in connection with that variable. So the question now is whether we'd want to use the same approach (promote, but only to type of interest) also for dynamic checks applied to local variables of type I agree that this adds to the number of locations where promotion can take place implicitly, but let's consider the trade-off: @lrhn wrote:
@leafpetersen wrote:
That's a real danger with any implicit promotion. However, if we promote more variables of type Do you have some good examples where this makes the code very hard to debug? Also, if the variable stays |
Bug: dart-lang/language#1362 Change-Id: I4d7e9a15a8f138e53b6f620d32a9f90e6ceed818 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/175902 Commit-Queue: Paul Berry <[email protected]> Reviewed-by: Johnni Winther <[email protected]>
I landed dart-lang/sdk@c171f92, which tests the current behavior (implicit downcasts don't promote). I'm going to leave the issue open in case folks want to discuss more. |
I just noticed a curious inconsistency in flow analysis.
Explicit casts from dynamic to another type cause type promotion, e.g.:
But implicit downcasts don't:
Both behaviors are sound, and both behaviors are implemented consistently between the analyzer and the CFE. So it's not necessary for us to do anything. But it seems a little strange that an implicit downcast and an explicit downcast would be treated so differently. Should we consider changing flow analysis so that
f(d)
also promotes?The text was updated successfully, but these errors were encountered: