Consider the following code:
void f<T extends void Function(int)>(List<T> x) {
x.first(0);
}
While analyzing the expression `x.first(0)`, the analyzer has to do two things:
- Convert the AST representation from a MethodInvocation (which is
what was initially parsed) to a FunctionExpressionInvocation
targeting a PrefixedIdentifier. This reflects the fact that the
invocation isn't a method invocation after all; it's a function call
invocation applied to a property get.
- Convert the static type of `x.first` from `T` to its bound, `void
Function(int)`, in order to type check the invocation. This is done
using the `TypeSystemImpl.resolveToBound` method.
Previously, `TypeSystemImpl.resolveToBound` was called as part of
converting the AST representation, and the resolved bound (`void
Function(int)` in this example) was stored as the static type of the
FunctionExpressionInvocation target. This led to some minor
inaccuracies in the AST representation (since the type returned by
`TypeSystemImpl.resolveToBound` is *not* the correct type of the
FunctionExpressionInvocation target).
With this change, the call to `TypeSystemImpl.resolveToBound` happens
during resolution of the FunctionExpressionInvocation instead,
allowing the target of the FunctionExpressionInvocation to retain its
correct static type.
I'm in the middle of a larger arc of work trying to introduce a new,
simpler mechanism for flow analysis to be told about the static types
of property gets, and part of that arc of work will involve
introducing a temporary check to verify that the old and new
mechanisms see the same static types. Fixing this incorrect type will
allow the temporary check to pass.
This change also has the side effect of fixing
https://github.com/dart-lang/sdk/issues/56907 (Analyzer fails to
propery type check invocations of complex expressions whose type is a
type parameter). This bug was happening in circumstances where a
FunctionExpressionInvocation arises directly from parsing (rather than
being created from a MethodInvocation), and the static type of the
target is a type variable. Previously, the analyzer was failing to
convert the static type to its bound when analyzing the
FunctionExpressionInvocation, so it was failing to type check the
invocation. Moving the call to `TypeSystemImpl.resolveToBound` into
FunctionExpressionInvocation resolution ensures that the type is
properly resolved to its bound in _all_ circumstances where a
FunctionExpressionInvocation occurs.
Fixes https://github.com/dart-lang/sdk/issues/56907.
Bug: https://github.com/dart-lang/sdk/issues/56907
Change-Id: Id648d5289a6cabe95b8410abd19898acb97fc5e7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390661
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
This CL updates the constant verifier to account for the null-aware
elements and map entries. Namely, the following is done:
* The entries and elements that won't be added to the map or set
literal due to being both null-aware and `null` won't be included in
the uniqueness checks, since they aren't added into the literal.
* The type the null-aware entries and elements are checked against is
updated to be the nullable version of the corresponding type
argument of the enclosing literal.
Change-Id: I20661d84dc26ee87c3893afe294bae5e4274b75f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390242
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Keerti Parthasarathy <keertip@google.com>
Background: null-shorting is a feature of Dart in which an expression
might evaluate to `null` because a `null` was found deep in a
subexpression, skipping evaluation of the rest of the expression. For
example, in the expression `a?.b(c).d`, if `a` evaluates to `null`,
execution will skip the evaluation of `c`, the method call to `b`, and
the get of `d`, will be skipped, and the whole expression `a?.b(c).d`
will evaluate to `null`. The analyzer needs to account for this by
making the static type of `a?.b(c).d` nullable, even if the type of
the `d` getter is not nullable.
The analyzer's implementation of null shorting works like this:
- When visiting a null-aware expression (such as `a?.b(c)` in the
above example), the analyzer uses
`NullShortableExpression.nullShortingTermination` to find the "null
shorting termination expression". This is the expression that will
evaluate to `null` if the null-shorting code path is taken
(`a?.b(c).d` in the above example).
- The null shorting termination expression is pushed onto the stack
`ResolverVisitor._unfinishedNullShorts`.
- After visiting an expression that might be a null shorting
termination expression, the analyzer passes the node that was just
visited to `ResolverVisitor.nullShortingTermination`, which checks
whether it matches any nodes at the top of the
`ResolverVisitor._unfinishedNullShorts` stack. If any nodes match,
they are popped off the stack, and the static type of the null
shorting termination expression is made nullable.
A subtlety with this approach is that if the resolution process has
rewritten the null shorting termination expression, then there are two
expressions in play: the old one (from the original AST, before
rewriting) and the new one (after rewriting). The node in
`ResolverVisitor._unfinishedNullShorts` is the old one, because the
code that pushes nodes onto the stack happens before rewrites. But the
node that needs to have its static type changed is the new one,
because that's the one that will wind up in the final resolved AST. In
fact, trying to change the static type of the old node would lead to a
crash, because the old node doesn't have a static type assigned.
Previous to this CL, the analyzer dealt with this situation by having
`ResolverVisitor.visitMethodInvocation` pass `discardType: true` to
`ResolverVisitor.nullShortingTermination`. This disabled the logic for
changing the type of the null shorting termination expression, which
avoided a crash, but it meant that the type was never updated
properly, leading to https://github.com/dart-lang/sdk/issues/56896.
The proper solution is to pass both the old and new nodes to
`ResolverVisitor.nullShortingTermination`. The old node is matched up
against `ResolverVisitor._unfinishedNullShorts`, and the new node is
used for marking the static type as nullable.
As part of this fix, I've changed the return types of methods in
`MethodInvocationResolver` from `FunctionExpressionInvocation?` to
`FunctionExpressionInvocationImpl?`. This is a harmless change, since
all these methods are private to the analyzer, and it avoids some type
casts in `ResolverVisitor.nullShortingTermination`.
I also added an assertion to `ResolverVisitor.nullShortingTermination`
to verify that the correct rewritten node is passed in (this assertion
relies on the `ResolverVisitor._replacements` expando, which is only
populated when assertions are enabled). Adding this assertion exposed
two other call sites that had to be updated (in
`ResolverVisitor.visitIndexExpression` and
`ResolverVisitor.visitPropertyAccess`). I've added additional analyzer
tests to cover these cases.
Fixes https://github.com/dart-lang/sdk/issues/56896.
Bug: https://github.com/dart-lang/sdk/issues/56896
Change-Id: I8119a05b4d9f386b1129e5419b823a61677358c5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/390560
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
When these tests were written
(https://dart-review.googlesource.com/c/sdk/+/178880), Dart did not
support field promotion. I was getting ready to add "why not promoted"
logic to flow analysis so that if a user tried and failed to promote a
field, and received an assignability error as a result, they would
receive a helpful error message explaining that field promotion was
not supported.
In order to generate this error message, flow analysis would have to
start keeping track of some *counterfactual* promoted types,
indicating what the type of certain expressions *would have been* if
field promotion had been supported. It was important to make sure that
these counterfactual promoted types were only used for error message
generation, and didn't actually change Dart semantics. So I wrote
these tests to help lock down the existing (non-promotion) behavior.
When field promotion was actually implemented in Dart 3.2, these tests
should have been given `@dart=3.1` annotations, since their purpose
was to validate the correct behavior of the implementation in
situations where field promotion *wasn't* enabled. I should have been
prompted to do this by a test failure, because when I enabled field
promotion by default in Dart 3.2, the behavior of the tests should
have changed. However, because of
https://github.com/dart-lang/language/issues/4127, the behavior didn't
change, so I didn't notice that these tests needed updating.
Now, I'm getting ready to fix
https://github.com/dart-lang/language/issues/4127, so in order to
prepare for that, I need to give these tests the proper `@dart=3.1`
annotations.
Bug: https://github.com/dart-lang/language/issues/4127
Change-Id: I59ad1eef7b01ccedcc8fb99e070a05273ac365e6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389781
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Collects files from `package:async_helper` and `tests/language`
that are generally useful, so that all test-related helpers are
in `package:expect`.
Moves the two libraries from `package:async_helper` into `package:expect`,
and the `tests/language/static_type_helper.dart` file too.
Deprecates `async_minitest.dart`, to follow `minitest.dart`,
expecting the Flutter use of it to have been fixed to not break
on deprecation (I believe Flutter no longer breaks builds on deprecations at all).
Patch 1 is the actual change.
Patch 2+4+8 is changing all existing references to the files.
Patch 6 ignores deprecation in files still using `async_minitest.dart`.
3+5+7+9 are updating this text to make the numbers match.
Then it's just test-expectations and small tweaks from there.
Change-Id: I1b665135b5fef9b9a0c3b340ffe9daf874d0174c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373120
Reviewed-by: Nate Bosch <nbosch@google.com>
Reviewed-by: Devon Carew <devoncarew@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
The CFE was passing the original LHS expression to
`flowAnalysis.ifNullExpression_rightBegin`. This was incorrect; it
needs to pass the rewritten LHS expression. Most of the time this was
harmless, since in most cases:
- The expression on the LHS of `??` was not promotable, in which case
passing the wrong expression didn't matter,
- Or the expression on the of `??` was a read of a local variable, in
which case there was no problem, since local variable reads don't
require rewriting.
However, in cases where the LHS of `??` is a read of a promotable
property, it does matter, since property reads are often rewritten
during inference.
Fixes https://github.com/dart-lang/sdk/issues/56874.
Bug: https://github.com/dart-lang/sdk/issues/56874
Change-Id: Ie42b96b0bc14faec38e8dbcb9e11534d4a1db0dc
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/389140
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
This CL implements type inference for null-aware colletion elements
and map entires in the Analyzer. The new functionality is dependent on
the `null-aware-elements` feature flag, since only when the flag is
enable, can the `keyQuestion` and `valueQuestion` properties of the
MapEntryLiteralEntry class be not null and the objects of the
`NullAwareElement` be created.
Part of https://github.com/dart-lang/sdk/issues/56836
Change-Id: I9243b01d5de097ae0d2ca3376807c6209ef0f830
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/387980
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
This CL changes the specification parser grammar to support a switch
expression that has zero cases (this is a missing update, the feature
specification already has it). It also changes several language tests
such that they expect a 'syntax error' rather than a 'compile-time
error'. This makes no difference for any tool except the specification
parser, for which it is needed (in general, a test that is expected
to have a compile-time error will parse just fine, so we need a
separate test outcome expectation for syntax errors).
Change-Id: Ifa00c11ce6c57053bd490e11a41d6e8d7b82a2d2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384600
Reviewed-by: Jonas Jensen <jonasfj@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
When determining whether a switch statement is exhaustive, it's
important for the exhaustiveness algorithm to ignore cases containing
`when` clauses, since a `when` clause creates the possiblity that the
case won't match.
Previously, the way this was done in the analyzer was for the
`SpaceCreator.createRootSpace` method to create an unknown space for
cases containing `when` clauses. This approach produced the correct
behavior when determining whether the switch statement as a whole was
exhaustive, but since it discarded information about the pattern being
matched, it limited the ability to determine whether an individual
case was reachable, leading to
https://github.com/dart-lang/sdk/issues/56710.
To fix this, `SpaceCreator.createRootSpace` is changed so that it
always produces a space that describes the case pattern, regardless of
whether a `when` clause is present, and instead,
`computeExhaustiveness` is responsible for ensuring that the case is
properly excluded from the determination of whether the switch is
exhaustive. This allows `computeExhaustiveness` to properly computate
whether each individual case is reachable, even for cases that have
`when` clauses.
This change in approach produced some minor differences in the test
cases in `pkg/_fe_analyzer_shared/test/exhaustiveness/data`, but these
differences are not user-observable.
Fixes https://github.com/dart-lang/sdk/issues/56710.
Change-Id: I36629a77c4c1832fb1b8abb6ea7b109e0ca14373
Bug: https://github.com/dart-lang/sdk/issues/56710
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384326
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
This test was out of place (since it doesn't contain any variable
patterns). Also, it was an exact copy of a test in
record_literal_switch_test.dart. There's no point in having the same
test in both locations, so remove it from the location where it
doesn't belong.
Change-Id: I1d3a786caba2b2591255b68c035eff40b2f08237
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/384565
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This warning is similar to the existing `UNREACHABLE_SWITCH_CASE`
warning, except that it warns if the `default` clause of a switch
statement is unreachable due to all the `case` clasuses fully
exhausting the switched type.
To make the implementation easier, I changed the API for the
`reportExhaustiveness` method in `_fe_analyzer_shared` (which is the
primary entry point to the shared exhaustiveness checker). Previously,
this method returned a list of `ExhaustivenessError`, where each list
element was either an `UnreachableCaseError` (indicating that a
certain case was unreachable) or a `NonExhaustiveError` (indicating
that the entire switch statement was not exhaustive). If the caller
passed in `false` for `computeUnreachable`, `UnreachableCaseError`s
would not be returned, so the returned list would either be empty or
contain a single `NonExhaustiveError`.
The new API renames the types for clarity:
- `NonExhaustiveError` becomes `NonExhaustiveness`, to highlight the
fact that it's not necessarily an error for the switch's cases to be
non-exhaustive; it's only an error if the scrutinee's static type is
an "always exhaustive" type and there is no `default` clause.
- `UnreachableCaseError` becomes `CaseUnreachability`, to highlight
the fact that it's not an error for a case to be unreachable; it's a
warning.
Also, the new API adds instances of `CaseUnreachability` to an
optional user-provided list instead of returning a newly created list;
this allows callers to communicate that they don't need to see
`CaseUnreachability` information by passing `null`. This frees up the
return type to simply be an instance of `NonExhaustiveness` (if the
cases are not exhaustive) or `null` (if they are exhaustive). This
makes it easier for the analyzer to decide whether to issue the new
warning, because it doesn't have to dig around the list looking for an
instance of `NonExhaustiveness`.
The new warning has an associated quick fix (remove the unreachable
`default` clause). This quick fix uses the same `RemoveDeadCode` logic
in the analysis server that the existing `UNREACHABLE_SWITCH_CASE`
warning uses.
Fixes https://github.com/dart-lang/sdk/issues/54575.
Bug: https://github.com/dart-lang/sdk/issues/54575
Change-Id: I18b6b7c5249d77d28ead7488b4aae4ea65c4b664
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/378960
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Clean up and optimize some RegExps, and fix uses of `.group`.
Switch to a newer language version, to be able to use newer features.
Add a little documentation about why some RegExps are as they are.
Add (tentative) warning for multitests.
Change-Id: I59f73b87ce30caaeca1c0e0aa7954af1b97abd1b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382620
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
This is the final CL for deferred loading. It wires up the library-module analysis logic to the compiler. With all the Translator module predicates implemented, code should now be generated in separate modules (assuming the flag is enabled).
This also handles the module naming scheme. For an invocation of dart2wasm like `dart2wasm main.dart out.wasm` this will produce files like `out.mjs, out.wasm, out_module1.wasm, out_module2.wasm, ...`. `out.wasm` is the main module that gets loaded on initialization. When the flag is disabled this will always be the only output.
If the flag is disabled then the `_importMapping` in `deferred.dart` will be empty and we will default to the same behavior as today which will be to just return an empty `Future`. When enabled, `loadLibrary` will fetch and instantiate the new module(s) before proceeding.
Change-Id: I0dd136c0af61b916be2a24b3d79052ff1b786b52
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/380440
Reviewed-by: Martin Kustermann <kustermann@google.com>
* Make dynamic module entry point fully compatible to script main
function (allow taking optional parameters and up to 2 arguments).
* Fix reading of function types within generic members.
* Add crashing tests to status files to avoid generation of
core dumps on the bots.
TEST=ci (vm-aot-dyn-linux-debug-x64)
Change-Id: Ibe8651ca13734101f2df2c8634f70ebf421dccef
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/382640
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Alexander Markov <alexmarkov@google.com>
Type for a closure with one argument (Closure-0-1) is subtype of type of
a closure with no arguments (Closure-0-0).
This allows calling the closure with no arguments in the generated code.
(This only happens when the Dart types align, i.e. the argument is
optional)
However instantiation vtable functions for e.g. Closure-1-1 currently
can't be as Closure-1-0, resulting in a type cast error in a code like:
void test<T>([T? x]) {}
void Function() x = runtimeTrue ? test : () {};
x();
Relax the instantiation context struct type in instantiation vtable
functions and downcast the generic closure struct type (type of the
instantiation closure) to the right type before calling instantiation
clsoure.
Fixes#56534.
Change-Id: I59f9b019c4dc8d2e26ee21f1f6c3c607af0be4d8
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381641
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Ömer Ağacan <omersa@google.com>
Previously, `HintCode.UNREACHABLE_SWITCH_CASE` was marked as
deprecated, and `WarningCode.UNREACHABLE_SWITCH_CASE` was an alias to
it. This created a slightly confusing situation, because it meant that
all code referring to the diagnostic had to refer to it as
`WarningCode.UNREACHABLE_SWITCH_CASE` (to avoid a deprecation lint),
but the diagnostic still _behaved_ like it was a hint, and therefore
test runner expectations still had to treat it as a hint.
It turns out that it's not really necessary to go through the
deprecation dance when changing the kind of a diagnostic, since (a)
members of `HintCode` and `WarningCode` aren't exposed through the
analyzer public API, and (b) ignore comments don't have to specify
whether something is a hint or a warning.
So the easiest way to clear up the confusion is to just remove
`HintCode.UNREACHABLE_SWITCH_CASE` entirely, and move its implemention
into `WarningCode.UNREACHABLE_SWITCH_CASE` (so that the latter is no
longer an alias).
Change-Id: I9ff7901ad38a2c168c5e54cbe0c1c52bf7c50186
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381103
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
For a class like this:
class A<T> {
T? value;
}
the implicit setter function (`A.value=`) has to check the argument
type.
TEST=language/covariant_field_implicit_setter_test
Change-Id: Ie990b79f631275fb0a7c88ec7d7dd3a82a784148
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/381000
Reviewed-by: Ömer Ağacan <omersa@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
This is a reland of commit e7658520bb
Fixes in the reland + context:
Type parameters emitted in implicit type checks on covariant mixin forwarding stubs may reference type arguments in anonymous classes. We reduce this to their mixin's implementing subclass to avoid generating RTI rules for anonymous classes.
Previous implementations would 'translate' type parameters to that of their mixed in type, but that strategy fails if the implementing subtype shuffles the order of type arguments relative to its mixed in type (demonstrated in the test - though not actually relevant in the Flutter break).
Original change's description:
> [ddc] Overhauling DDC's generic class representation.
>
> Prior to this change, DDC represented generic classes as closures over type parameters (with type arguments provided at runtime), which tightly coupled generic class definitions with their types and concrete instantiation.
>
> This rewrite decouples this representation, letting us 1) bind type information late and 2) separate generic class definitions from their instantiation.
>
> Notable changes:
> - Generic classes are now declared at top level (rather than within in closures).
> - RTIs are now passed to generic class constructors at runtime (except for JS Interop classes). Only the instantiated class's RTI is required (and it's retained up the type hierarchy).
> - Type signature resolvers are now lambdas that accept a type environment RTI at runtime. While signatures are still attached early, their instances' RTIs are now needed at runtime.
> - Generic classes, constructors, and factories are now evaluated in a 'Class' type environment.
> - An `RtiTypeEnvironment` is introduced to represent lookups on an RTI type environment bound to a parameter. These are used when evaluating type signatures and at constructor/factory bodies.
> - Type recipes now emit Class type parameters with names - but continue to emit method type parameters with de Bruijn indices. This is because indices aren't stable across subtypes.
> - Certain debugger functions now require instances (e.g.,`getClassMetadata`).
> - Adds a special flag for non-external JS interop factory constructors to emit 'true' types (versus 'any').
>
> Change-Id: I7cbeaaf666dd4f9bd5e3ef22a1163a659fc0ee48
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365863
> Reviewed-by: Srujan Gaddam <srujzs@google.com>
> Reviewed-by: Kallen Tu <kallentu@google.com>
> Reviewed-by: Nicholas Shahan <nshahan@google.com>
> Reviewed-by: Nate Biggs <natebiggs@google.com>
> Commit-Queue: Mark Zhou <markzipan@google.com>
Change-Id: I9b6f69b7150631f28442675c4230e093e3b821d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379511
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
To be able to know when we are generating a source map, make `dart
compile wasm` aware of the `--no-source-maps` flag.
The "name" segments of source mappings are also made `null` with this
patch. Browsers don't use that segment and binaryen doesn't support it.
Change-Id: I7b52c8fb7cef92ed60547e97ad137e0cd3967f26
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/378421
Commit-Queue: Ömer Ağacan <omersa@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This reverts commit e7658520bb.
Reason for revert: Causing failures in both Dart->Flutter roller and web_dev package.
Original change's description:
> [ddc] Overhauling DDC's generic class representation.
>
> Prior to this change, DDC represented generic classes as closures over type parameters (with type arguments provided at runtime), which tightly coupled generic class definitions with their types and concrete instantiation.
>
> This rewrite decouples this representation, letting us 1) bind type information late and 2) separate generic class definitions from their instantiation.
>
> Notable changes:
> - Generic classes are now declared at top level (rather than within in closures).
> - RTIs are now passed to generic class constructors at runtime (except for JS Interop classes). Only the instantiated class's RTI is required (and it's retained up the type hierarchy).
> - Type signature resolvers are now lambdas that accept a type environment RTI at runtime. While signatures are still attached early, their instances' RTIs are now needed at runtime.
> - Generic classes, constructors, and factories are now evaluated in a 'Class' type environment.
> - An `RtiTypeEnvironment` is introduced to represent lookups on an RTI type environment bound to a parameter. These are used when evaluating type signatures and at constructor/factory bodies.
> - Type recipes now emit Class type parameters with names - but continue to emit method type parameters with de Bruijn indices. This is because indices aren't stable across subtypes.
> - Certain debugger functions now require instances (e.g.,`getClassMetadata`).
> - Adds a special flag for non-external JS interop factory constructors to emit 'true' types (versus 'any').
>
> Change-Id: I7cbeaaf666dd4f9bd5e3ef22a1163a659fc0ee48
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365863
> Reviewed-by: Srujan Gaddam <srujzs@google.com>
> Reviewed-by: Kallen Tu <kallentu@google.com>
> Reviewed-by: Nicholas Shahan <nshahan@google.com>
> Reviewed-by: Nate Biggs <natebiggs@google.com>
> Commit-Queue: Mark Zhou <markzipan@google.com>
Change-Id: I8ea12847bb2a4d096db0799c85f3175f1c5df3be
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/379420
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
Auto-Submit: Nate Biggs <natebiggs@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Jake Macdonald <jakemac@google.com>
Prior to this change, DDC represented generic classes as closures over type parameters (with type arguments provided at runtime), which tightly coupled generic class definitions with their types and concrete instantiation.
This rewrite decouples this representation, letting us 1) bind type information late and 2) separate generic class definitions from their instantiation.
Notable changes:
- Generic classes are now declared at top level (rather than within in closures).
- RTIs are now passed to generic class constructors at runtime (except for JS Interop classes). Only the instantiated class's RTI is required (and it's retained up the type hierarchy).
- Type signature resolvers are now lambdas that accept a type environment RTI at runtime. While signatures are still attached early, their instances' RTIs are now needed at runtime.
- Generic classes, constructors, and factories are now evaluated in a 'Class' type environment.
- An `RtiTypeEnvironment` is introduced to represent lookups on an RTI type environment bound to a parameter. These are used when evaluating type signatures and at constructor/factory bodies.
- Type recipes now emit Class type parameters with names - but continue to emit method type parameters with de Bruijn indices. This is because indices aren't stable across subtypes.
- Certain debugger functions now require instances (e.g.,`getClassMetadata`).
- Adds a special flag for non-external JS interop factory constructors to emit 'true' types (versus 'any').
Change-Id: I7cbeaaf666dd4f9bd5e3ef22a1163a659fc0ee48
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/365863
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Reviewed-by: Kallen Tu <kallentu@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Nate Biggs <natebiggs@google.com>
Commit-Queue: Mark Zhou <markzipan@google.com>
Each wildcard variable will have a unique name meaning that each local, formal, and type parameter named `_` will be named something similar to `_#wc<index>#<type>`.
This will allow the DDC tests to pass.
Change-Id: Ic5362e46142c4a51cd461280ca33a8a5ba5b910f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/373621
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>