dart-sdk/pkg/analyzer/test
Paul Berry 130d6199c3 Field promotion: make the core promotability algorithm sharable; fix bugs
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>
2023-07-18 18:54:26 +00:00
..
dart Breaking changes for analyzer version 6.0.0 2023-06-16 16:31:27 +00:00
error
file_system
generated Use 'augmented' for ClassHierarchy. 2023-07-17 21:12:49 +00:00
id_tests Deprecate ExecutableElement.returnType, use returnType2 instead. 2023-06-29 23:16:59 +00:00
instrumentation [analysis_server] Exclude instrumentation log file from logged watch events to prevent loops 2022-12-12 20:09:36 +00:00
snippets
source Add AnalysisError.tmp() constructor, deprecate the default one. 2023-05-08 14:39:29 +00:00
src Field promotion: make the core promotability algorithm sharable; fix bugs 2023-07-18 18:54:26 +00:00
util Link augmented methods and augmentations, fill 'augmented.methods' 2023-07-14 18:32:10 +00:00
embedder_tests.dart Remove TestPathTranslator and other related utilities. 2023-01-18 21:00:49 +00:00
test_all.dart
utils.dart Use InvalidType instead of DynamicType when unresolved. 2023-05-10 20:38:48 +00:00
verify_diagnostics_test.dart [analyzer] Introduce a new annotation @visibleOutsideTemplate 2023-06-08 18:47:15 +00:00
verify_docs_test.dart Reland "[analyzer] Move 4 more HintCodes to be WarningCodes, UNUSED_*" 2023-03-28 21:26:58 +00:00
verify_tests_test.dart [analysis_server]/[analyzer] Change package_path alias -> path 2023-07-17 16:48:36 +00:00