dart-sdk/pkg/front_end
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
..
benchmarks
lib [cfe] Handle exhaustiveness checking in expression evaluation 2023-07-18 10:17:49 +00:00
outline_extraction_testcases
parser_testcases [parser] Use endInvalidYieldStatement for async methods 2023-06-14 12:10:59 +00:00
test Field promotion: make the core promotability algorithm sharable; fix bugs 2023-07-18 18:54:26 +00:00
testcases [cfe] Handle exhaustiveness checking in expression evaluation 2023-07-18 10:17:49 +00:00
tool Make utf8.encode() have Uint8List return type 2023-07-11 08:54:33 +00:00
analysis_options.yaml
analysis_options_no_lints.yaml
error_recovery.yaml
LICENSE
messages.status [vm] Async FFI callbacks 2023-06-28 01:00:18 +00:00
messages.yaml [vm] Async FFI callbacks 2023-06-28 01:00:18 +00:00
OWNERS
PRESUBMIT.py
pubspec.yaml
README.md
testing.json
testing_with_lints.json

Front end for Dart

This package provides a low-level API for use by compiler back ends that wish to implement the Dart language. It is intended for eventual use by dev_compiler, dart2js, and the Dart VM. In addition, it will share implementation details with the analyzer package--this will be accomplished by having the analyzer package import (and re-export) parts of this package's private implementation.

End-users should use the dart analyze command-line tool to analyze their Dart code.

Integrators that want to write tools that analyze Dart code should use the analyzer package.

Note: A previous version of this package was published on pub.dev. It has now been marked DISCONTINUED as it is not intended for direct consumption, as per the notes above.