-
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
Add a flag to disable implicit downcasts #26583
Comments
Great idea! Yeah we should do this. For what it's worth, shouldn't be all that hard to create this flag. We already find them, more or less, but we suppress them in most cases (to make upgrading to strong mode a little easier on folks). The hardest part is probably just adding the option to analyzer_cli and analysis_options. Note, this wouldn't cover covariant generics, e.g. this would still be allowed at compile time: main() {
var ints = <int>[1, 2, 3];
List<Object> objects = ints;
objects.add('hello'); // runtime failure
} We could add a flag for invariant generics as well, but that's a good deal bigger task. Also it would be a shame because we have some interfaces like |
For my part, I'm much less worried about variance bugs than I am about other implicit downcasts. |
Interesting ... it looks like this option kind of exists internally (not sure if it's exposed) as "strongModeHints", however, that will issue a hint about dynamic invokes as well, which is probably not what we want. |
A few other interesting findings: There's something called AssignmentCast for We have a special case for There is also cast from |
Personally I would prefer having a warning there and having to write |
What about:
all defaulting to true (allowed). Casting from
defaults to true (allowed), and sets all three of the above flags. I don't love that two of the three cover cast locations, while the third covers a specific source type. Maybe we should just implement the first and third flags, and if we get a feature request for the middle one we could add it. My sense is that if you want to avoid implicit downcasts, then implicit downcasts from dynamic are probably the most important ones to catch (since inference failures will show up as things being dynamic). |
A nice, thanks for those thoughts! Based on that, I'm implementing one flag that disables all of those implicit casts. |
https://codereview.chromium.org/2054443002/ starts making some progress. Assuming that approach looks good, there is follow up in analyzer_cli & analysis_options. |
oops, not actually fixed yet! My commit message incorrectly triggered auto-close. |
https://codereview.chromium.org/2060013002/ - further refactoring from first CL. Changes the implicit cast feature to be better handled (directly in StrongTypeSystem assignability check). After that CL, I can work towards adding an option toCLI/server/DDC. Bonus: it will make your DDC compilation a tad faster too! We can avoid a tree copy that adds the implicit casts. |
Also changes implicit casts errors to be determined by the type system isAssignableTo code, and updates our tests to show the user-facing error levels (StaticTypeWarningCode is upgraded to errors as far as users can see, but this wasn't visible in the tests, which showed these as "warnings"). found while looking at #26583 R=brianwilkerson@google.com, leafp@google.com Review URL: https://codereview.chromium.org/2060013002 .
Internal option is now available in Analyzer. Next step here is to add the user-facing option to analyzer_cli, analysis_server and DDC. |
Going to close this as implemented, but we still need to document it and expose through the UI, along with a few other flags. That's covered in: #26782 |
I'm seeing strange behavior testing this out on real world code, it might be a problem in my previous CL. What is going wrong is lots of "hints" about types, for example this expression: var lines = <String>[];
// ...
lines.map((l) => ' * $l'); produces the hint:
Shouldn't we know that's a String -> String? It's returning a string interpolation. And why does it show up as a "hint" if we think it's a type error... ? I'm going to investigate that further before exposing this flag. |
That looks like an analyzer propagated type hint to me. Maybe something in your CL is letting a propagated type through where it shouldn't? |
aha, propagated types! Forgot about those. That might be it. I don't think the implicit cast change alters any types, but it does change the StrongTypeSystemImpl isAssignableTo logic. So perhaps propagated types use that (likely in ErrorVerifier). In which case, they've been tightened as well, which reveals that we had wrong type stored on the function. At least, that's a theory. |
Reproduced with a simple test: void test_implicitCasts_genericMethods() {
addFile('var x = <String>[].map((x) => "");');
check(implicitCasts: false);
} Analyzer computes propagated types for lambda expressions passed to methods using _inferFunctionExpressionsParametersTypes. This happens before we've computed the strong mode staticType for the function, so it ends up storing the wrong type. I'm tempted to skip propagated type inference for lambda expressions if in Strong Mode. It already does lambda inference, so it seems like extra work for no benefit in that case. |
CL out for that: https://codereview.chromium.org/2145273002/ |
I want to ensure that there are no implicit downcasts in my code. I never intend to write them, so I expect that all instances of them are likely to be bugs. I understand that it's complex and wide-reaching to make them errors everywhere (as in #26437), but adding a flag that disables them would only affect users who enable this flag. It would probably also make it easier to determine how disruptive it would be to disable them entirely in strong mode.
The text was updated successfully, but these errors were encountered: