mirror of
https://github.com/dart-lang/sdk
synced 2024-09-15 23:49:47 +00:00
130d6199c3
In the following code, it's not safe for the field `C._f` to undergo type promotion, because a variable with static type `C` might have type `D` at runtime, in which case `C._f` will get dispatched to `noSuchMethod`, which is not guaranteed to return a stable result. class C { final int? _f; } class D implements C { noSuchMethod(_) => ...; } foo(C c) { if (c._f != null) { print(c._f + 1); // UNSAFE! } } Therefore, in order to determine which fields are promotable, the implementations need to analyze enough of the class hierarchy to figure out which field accesses might get dispatched to `noSuchMethod`. Currently, the CFE does this by following its usual algorithm for generating `noSuchMethod` forwarders before trying to determine which fields are promotable. The analyzer, on the other hand, doesn't have an algorithm for generating `noSuchMethod` forwarders (since it doesn't implement execution semantics); so instead it has its own logic to figure out when a `noSuchMethod` forwarder is needed for a field, and disable promotion for that field. But there's a chicken-and-egg problem in the CFE: the CFE needs to determine which fields are promotable before doing top-level inference (since the initializers of top-level fields might make use of field promotion, affecting their inferred types--see #50522). But it doesn't decide where `noSuchMethod` forwarders are needed until after top-level inference (because the same phase that generates `noSuchMethod` forwarders also generates forwarders that do runtime covariant type-checking, and so it has to run after all top level types have been inferred). To fix the chicken-and-egg problem, I plan to rework the CFE so that it uses the same algorithm as the analyzer to determine which fields are promotable. This CL makes a first step towards that goal, by reworking the analyzer's field promotability algorithm into a form where it can be shared with the CFE, and moving it to `package:_fe_analyzer_shared`. Since this required a fairly substantial rewrite, I went ahead and fixed #52938 in the process. Fixes #52938. Change-Id: I9e68f51b3ea9a967f55f15bdc445cc1c0efdabdd Bug: https://github.com/dart-lang/sdk/issues/52938 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/313293 Reviewed-by: Johnni Winther <johnniwinther@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Sigmund Cherem <sigmund@google.com> Commit-Queue: Paul Berry <paulberry@google.com> |
||
---|---|---|
.. | ||
analysis_options | ||
clients | ||
context | ||
dart | ||
dartdoc | ||
diagnostic | ||
error | ||
exception | ||
fasta | ||
file_system | ||
generated | ||
hint | ||
ignore_comments | ||
lint | ||
manifest | ||
plugin | ||
pubspec | ||
services | ||
source | ||
summary | ||
summary2 | ||
task | ||
test_utilities | ||
util | ||
utilities | ||
workspace | ||
error.dart | ||
string_source.dart |