-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Consider taking final classes into account for "impossible cast" warnings #29548
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
Comments
The final classes in Dart are int x = null;
bool y = (x as bool); would "succeed". With a whole-program analysis, we can warn if the cast is impossible in the program, even if it's not impossible in general, so I think the analyzer is the right place for such a warning. So, is it important to handle the few cases of the four final classes earlier? Does it actually happen in practice? List<int> x = ...;
List<bool> y = x as List<bool>; /// Failure? (Except for List<Null>)? |
I know that they've discussed this topic in the Scala community in terms of intersections: If S&T is the empty type then cast-from-S-to-T will fail, and if S&T is a non-empty type then we generally can't know for sure that it will fail. So the intersection criterion is a pretty accurate way to see it. I believe we cannot hope to determine type emptiness in the general case (and certainly not during separate compilation), so this is inherently a "best effort" thing. With that in mind I think it's an OK policy to go ahead and pick the low-hanging fruit. However, we might want to wait until we get support for non-null types (or at least a few non-null predefined types), such that the failure is actually guaranteed? Or maybe the error message could say "If you really want to test for |
Unless we add user defined final (sealed) classes, which I'd still like us to do.
Yes, we could do this as a lint, but I don't want to specify it as a language error since I want us to be able to do modular analysis.
I don't think so. Not without whole program analysis, or maybe unless we forbid implementing the same class twice. If you have a generic class |
We can no longer have classes that implement both |
As Lasse mentioned here, we do have So the example that we considered will succeed in some cases, and it seems overly strict to make it an error: List<int> x = ...; // Actually a `List<Null>`.
List<bool> y = x as List<bool>; After all, the whole point of using It's another matter as soon as we have non-null types, because they will enable us to say for sure that these final classes (in various positions including type arguments) can provide a guarantee that a cast will fail at run time. |
Brought over from #33933 (duplicate): We don't have user-defined sealed types yet, but they do exist. Consider: void main() {
int x = 5;
if (x is String) {
print('...');
}
} I'd expect |
#29547 proposes extending strong mode impossible cast warnings to explicit casts as well as implicit casts. For implicit casts, we are at least guaranteed that the types are subtype related, but for explicit casts we allow casts between non-subtype related classes, since there may be a type somewhere which implements both. However, if either class is final and they are not subtype related, then the only way the cast can succeed is if the value is null, which is highly unlikely to be what the user intended. We should consider taking this into account and issuing an error.
cc @Hixie @lrhn @munificent @eernstg @floitschG
The text was updated successfully, but these errors were encountered: