This makes tests more reproducible, and makes it easier to copy commands between workspaces, or between a failing bot and a local workspace.
Change-Id: Ic8dd10a3540f314a406e5c5b0a23d97032e5d01d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508364
Reviewed-by: Alexander Aprelev <aam@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
The experimental `dart:ffi` support predates deferred loading
implementation. Any use of FFI features would lazily import `ffi.memory`
into the (fixed coded) main module.
This CL now lazily imports the `ffi.memory` module into all modules that
operate on the memory.
=> This will now allow a flutter app that is compiled with dart2wasm
in deferred loading mode to possibly defer parts of flutter
engine code that uses FFI into deferred modules.
Issue https://github.com/dart-lang/sdk/issues/56952
Change-Id: Idf821ce2dd92c36ac1be9dae24307516a1ae86d9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510760
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
'canInvokeTypeEquality' was assuming that if a single case was a Type expression, then type equality should be used for the whole switch statement. This is incorrect because if a single case is a type expression but the rest are, for example, ints (as in the fixed test) then the int cases should be compared with identical while only the type expression should be compared with ==.
More importantly, the expected type of the case expression constants should be top type rather than the Type type. Top type is the union of Type and the other case type.
Switches that only include Type expressions will now use "top" type as well but in general switching on a Type expression is an antipattern we shouldn't optimize for. And the impact of not specializing the switch type to Type should be very minimal.
Fixes: https://github.com/dart-lang/sdk/issues/63476
Change-Id: Ib96172f157d8cf3093199e5127d4835e7b25011c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509920
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
When generating SSA jump instructions (HContinue and HBreak) for AST break statements, ensure that we only select labels from the target's label list that are explicitly marked as valid continue (isContinueTarget) or break (isBreakTarget) targets.
Previously, handler.labels.first was selected indiscriminately if non-empty, which caused unlabeled continue statements inside loops that had an outer break label to incorrectly generate labeled continue jumps targeting the break label.
Fixes: https://github.com/dart-lang/sdk/issues/63456
Change-Id: Ic497776141a192edb0930f4585cdaae2feecb3d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/510280
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
The CFE constructor tear-off lowerings introduce extra static methods.
Tear-off constants refer to them as `StaticTearOffConstant`s. They
just forward the call to the actual generative, factory or
redirecting factory constructors.
We can avoid these intermediary methods by not using the CFE lowerings.
Change-Id: I1dc1203d6b3023cf1f13bc204a2628ec8a3aebc4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/508562
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Srujan Gaddam <srujzs@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
Report direct recursive interface inheritance diagnostics on the
inheritance clause that introduces the cycle, rather than on the class
or mixin name. This gives a more precise target for self-references in
extends, implements, on, and with clauses.
Track recursive inheritance reporting per interface element across
fragments so that augmentation clauses can produce the specific
diagnostic when they introduce the cycle. Defer the generic cycle
diagnostic while earlier fragments still have later augmentations to
inspect, and use the element target as the fallback location for
indirect cycles.
Update diagnostic expectations to match the new locations and cover
augmentation and part-file cases for recursive extends, implements, on,
and with clauses.
Change-Id: I480a56e4b766d704c290d67d9ca4f6a73a2f655b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/507300
Reviewed-by: Paul Berry <paulberry@google.com>
Implement api methods to create and shutdown isolates from IsolateGroup-bound callbacks (normally invoked from native code), run dart code on such isolates.
The rest of the api is not implemented yet.
TEST=tests/ffi/threading_test.dart
BUG=https://github.com/dart-lang/sdk/issues/62407
CoreLibraryReviewExempt: vm-only change to isolate library
Change-Id: I0271ead8ba011dfe9d7953769415d6a88a962854
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486522
Commit-Queue: Alexander Aprelev <aam@google.com>
Reviewed-by: Ryan Macnak <rmacnak@google.com>
This CL introduces support for anonymous block methods (that is,
`e.{ print(this); }` as opposed to `e.=> print(this);`). It introduces
the notion of a `ReturnContext` which is used to change the semantics
of a return statement when it returns from an anonymous method (where
it works like a `break` that terminates the execution of the block
which is the body of the enclosing anonymous method), but keeps the
semantics of return statements returning from a function (including
function literals) still have the same semantics as today.
Change-Id: I404459361fbb7c2e495e46d1bd29924063f3aac4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/503800
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
Fixes#63418
When IOOverrides are active, `fseGetType` and `fseGetTypeSync` used
`utf8.encode(path)` which does not null-terminate the path. Native
APIs require null-terminated paths. Through luck the sync path worked
but the async path failed with `notFound`.
Update them to use `FileSystemEntity._toUtf8Array(path)` which correctly
null-terminates the path.
Tested: added a regression test to tests/standalone/io/io_override_test.dart
TAG=agy
CONV=ab6af504-d536-4a8d-88be-bc487b60e24d
R=bkonyi@google.com
CoreLibraryReviewExempt: No API changes.
Change-Id: I24e31efdcbecc703800b96a144e41a095a445cff
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505201
Reviewed-by: Ben Konyi <bkonyi@google.com>
Commit-Queue: Nate Bosch <nbosch@google.com>
Auto-Submit: Nate Bosch <nbosch@google.com>
The tests in `tests/standalone/package/` don't use the top level
`package_config.json` file; they use their own internal file, which
apparently hasn't been updated recently. This change bumps the version
of `package:expect` in that file to version 3.13, which will allow
`package:expect` to start using Dart language 3.13 features without
breaking tests.
Change-Id: Ia2975d540aa503e8f69944e0e1c275c56a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505580
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
Some features in `dart:_wasm` are relevant for all WebAssembly targets
(like interop types or memory intrinsics). Others, in particular the
helper methods to convert between `WasmExternRef` and `JSAny`, don't
make sense for the standalone target.
To be able to remove the `js_interop` library from the standalone
target, we need to stop importing it from `dart:_wasm`. To prepare that
step, this moves the helpers to a new library (`dart:_js_interop_wasm`)
and re-exports them from `dart:_wasm`.
Once Flutter has migrated to the new import, the export can be removed.
Bug: https://github.com/dart-lang/sdk/issues/63166
Change-Id: I13fe875e509a13d16c48d420a5927d3130b90736
Cq-Include-Trybots: luci.dart.try:flutter-analyze-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505080
Reviewed-by: Martin Kustermann <kustermann@google.com>
Auto-Submit: Simon Binder <oss@simonbinder.eu>
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
This CL changes the code generation for `dart2js` (and not for any other
backend) such that the variable holding the receiver of an anonymous
method invocation is declared as a normal local variable rather than
being a `Let` variable. This is needed because `dart2js` supports
capturing the former, but not the latter.
Change-Id: I054805f7006306186f2c6dfe36d7162b42293ae1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/503420
Reviewed-by: Stephen Adams <sra@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
This migrates the `String` implementation from using JS interop to
explicit host imports for the standalone target.
This moves a few helper methods shared between the JS and standalone
targets to `dart:_string_helper`. This also moves the embedder regexp
implementation to `dart:_string` to be able to access internals in some
string methods (similar to how the JS implementation special-cases
`JSSyntaxRegExp`).
This removes the final real use of JS-interop in the standalone target.
So, we can:
- Remove internal JS helper libraries from the target.
- Skip JS-interop transformations in the compiler.
- Stop emitting a helper module and support script.
Because `js_interop` is imported in `dart:_wasm`, we can't remove the
library entirely. This replaces it with a stub to avoid compilation
errors, a proper removal is tracked in dartbug.com/63166.
Change-Id: Ide495c210c3a272438deebf8fe4f3f44ba314ffa
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/501960
Reviewed-by: Martin Kustermann <kustermann@google.com>
Reviewed-by: Kevin Moore <kevmoo@google.com>
Commit-Queue: Martin Kustermann <kustermann@google.com>
The former contents of the VM isolate are now included into each isolate group. This makes each isolate group's heap independent, and in particular allows each heap to be allocated to a separate pointer cage (not done in this CL).
The duplicated stubs that allowed PC relative calls are removed, since the originals can now be the target of PC relative calls.
The bootstrapping needing to load an AppJIT or AppAOT snapshot is reduced to allocating the oddballs. The code is entirely dropped in the AOT runtime, but the JIT runtime still has it to allow for flags to affect the compilation of the stub code. Further refactoring might be able to remove this for the JIT runtime too, with only gen_snapshot knowing how to bootstrap.
Class serialization no longer distinguishes predefined classes.
The page containing null is marked as never-evacuate. null, false and true must not move because the compiler relies on their low bits having certain patterns for some optimizations. (Previously, the entire VM isolate heap never moved.)
Compaction is disabled for IA32. Due to register pressure, some stub calls must not use a scratch register and embed the address of Code.
The page containing the call-through-safepoint stub is frozen when running with --write-protect-code and the stub is created at runtime (instead of loaded from an AppJIT or AppAOT snapshot). This stub must remain executable even during a safepoint, as a foreign call might during return during a safepoint and only block after the stub directs it to the runtime.
The snapshot symbols are renamed to kDartSnapshotData and kDartSnapshotText. There is no need to distinguish the VM isolate's snapshot, and snaphots are per isolate group not per isolate. Aliases with the old names are added to ease migration.
Some global flags that were automatically set based on the VM isolate's snapshot are now isolate group flags and automatically set by the isolate group's snapshot.
TEST=ci
Change-Id: Iee82016057d609112e9b021d178fc3d4d18b5044
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500621
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Tess Strickland <sstrickl@google.com>
SLSA-Policy-Verified: SLSA Policy Verification Service <devtools-gerritcodereview-exitgate@google.com>
Commit-Queue: Ryan Macnak <rmacnak@google.com>
It is disabled when augmentations feature is enabled.
This is not a breaking change, because CFE did report this error.
The relevant reason is indirect, not a single sentence saying “on A
implements A is forbidden”.
Spec chain:
1. In dartLangSpec.tex:6019, a mixin declaration is modeled as:
`mixin N<T...> on T1, ..., Tn implements I1, ..., Ik { ... }`
2. In dartLangSpec.tex:6065, the mixin interface M_I is defined as if
by:
`abstract class N<T...> implements T1, ..., Tn, I1, ..., Ik { ... }`
and dartLangSpec.tex:6078 says it is a compile-time error for the mixin
if that synthetic class declaration would be a compile-time error.
3. In dartLangSpec.tex:5189, class superinterfaces say:
It is a compile-time error if two elements in the type list of the
IMPLEMENTS clause of a class C specifies the same type T.
So:
`mixin M on A implements A {}`
is checked like:
`abstract class M implements A, A {}`
which violates the duplicate implements type rule.
Change-Id: I29e5fa17c47d111346ef6a6e321ab5dbab985ad1
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/503501
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
https://dart-review.googlesource.com/c/sdk/+/498840 added support for
promotion of properties (private, final instance variables with a name
which isn't used much for other purposes) in the context of anonymous
methods.
This CL reduces the set of situations where this feature is enabled such
that only `this` will allow property promotions to be carried in (such
that `this._x` is promoted in `v.=> this._x` when `v` is such that
`v._x` has been promoted before the anonymous method occurs). It also
generalizes the mechanism such that property promotions are carried out
(so we can do `if (v.=> _x is int) v._x.isEven;`).
Tests has been adjusted accordingly.
Change-Id: Ibe70713d3d9c89a6d95f9c3dd28df8f147cb518d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502660
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
When deferred loading was enabled the dynamic dispatch class ID table
was incorrectly assigning class IDs to the wrong module. If a contiguous
target segment included classes/targets from different modules, all of
them were getting assigned to the module of the first class/target in
that segment.
This was causing spurious NSM exceptions as the necessary rows in the
table might not be populated for a dynamic call if the module the
segment was assigned to wasn't loaded yet.
To fix this we end the segment if the next target does not belong to the
same module as the active segment.
The new test fails with an NSM exception prior to this fix.
Change-Id: I07bc4fdb5a8bff1bfad5fe17f45c8076a965a775
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/502860
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Adds two new getters to int for bit-counting: trailingZeroBitCount
(ctz) and oneBitCount (popcount). On native platforms they operate
on the full 64-bit two's-complement representation; on the web they
operate on the least-significant 32 bits.
Implementations:
- VM: unified C++ natives Integer_trailingZeroBitCount /
Integer_oneBitCount on _IntegerImplementation, using
Utils::CountTrailingZeros64 and Utils::CountOneBits64. The receiver
may be _Smi or _Mint at runtime.
- dart2js / DDC: clz32-based ctz and a SWAR popcount.
- dart2wasm: inlined i64.ctz and i64.popcnt intrinsics.
leadingZeroBitCount (clz) is intentionally excluded from this CL: its
result depends on the platform integer width (e.g. 1.leadingZeroBitCount
is 31 on web, 63 on native), and the same value can be derived from
the existing bitLength getter when needed.
Asm intrinsification on native architectures is intentionally left for
a separate follow-up CL.
Work towards https://github.com/dart-lang/sdk/issues/6486 (this CL
covers popcount and ctz from the bit-twiddling list; clz, rotate,
reverse, and others remain).
Work towards https://github.com/dart-lang/sdk/issues/1053 (efficient
BitSet implementation).
Bug: https://github.com/dart-lang/sdk/issues/52673
Bug: https://github.com/dart-lang/sdk/issues/38346
TEST=tests/corelib/int_bit_count_test
Change-Id: I8a5cdb5c91360478f47bbd6b9c84ca1c477aa8c7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498041
Reviewed-by: Slava Egorov <vegorov@google.com>
Commit-Queue: Slava Egorov <vegorov@google.com>
Reviewed-by: Stephen Adams <sra@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Auto-Submit: Modestas Valauskas <valauskasmodestas@gmail.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
In some cases, closure contexts were being left out of the parent chain
of their children because they were empty at the time the child closure
was created. If a usage appeared later in the visit of the parent, the
context would no longer be empty but the child would already be created
without a parent.
This was easiest to recreate in sync* function because unlike async, it
doesn't introduce hoisted helper variables (these immediately mark the
parent as non-empty).
In the attached bug the repro only happens with named parameters because
TFA transforms the named parameter into a Let that introduces a variable
before the closure with the usage in the let body after the closure. The
new test explicitly introduces the same pattern of a variable declared
before the closure and used after it.
The fix here is to not eagerly check for emptiness of the parents.
Instead we post-process the Contexts and relink the parent tree skipping
any empty nodes.
Bug: https://github.com/dart-lang/sdk/issues/63264
Change-Id: I2f75506b9fa879544b1a606d8f157fbd44ba8ce2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500680
Commit-Queue: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
This CL adds support for promotion of certain private final instance
variables along with anonymous methods. The promotions do not differ
from the ones which are already available in Dart without anonymous
methods, but it requires some generalizations to handle the changing
value of `this` which is made possible by anonymous methods.
Change-Id: I720a5fa6d29a8a7d19bb2e167dc135f97492b525
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498840
Reviewed-by: Paul Berry <paulberry@google.com>
This adds an AsyncModifier class that holds both the AsyncMarker, used in the kernel encoding, and the file offset of the async modifier. This is used throughout the front end and ensures that the correct offset is used for errors reported on the async modifier.
Change-Id: If16d293ffb9b2e8fa8eca8c65f7548d920c5d56b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500720
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
This CL enables the primary constructors feature by default in Dart 3.13.
The primary constructors feature is a brevity feature. There are no new semantics, but it allows us to express declarations in a less verbose way.
This feature allows one constructor and a set of instance variables to be specified in the header of a declaration.
Currently a declaration with a constructor and some fields is written as:
```dart
// Current syntax.
class Point {
int x;
int y;
Point(this.x, this.y);
}
```
With a primary constructor, we would write the above as:
```
class Point(var int x, var int y);
```
If a primary constructor needs an initializer list or a body, they can be
specified inside the class using the `this` body syntax:
```dart
class Point(var int x, var int y) {
this : assert(x >= 0) {
print('Point created at $x, $y');
}
}
```
As part of this feature, you can also use the `new` and `factory` keywords to
declare constructors in the class body without repeating the class name:
```dart
class Point {
int x, y;
// Equivalent to Point(this.x, this.y)
new(this.x, this.y);
// Equivalent to Point.origin()
new origin() : x = 0, y = 0;
// Equivalent to factory Point.clone(Point other)
factory clone(Point other) => Point(other.x, other.y);
}
```
To learn more about the feature, check out the feature specification located here: https://github.com/dart-lang/language/blob/main/accepted/future-releases/primary-constructors/feature-specification.md
Tested: Has existing language, CFE, analyzer, analysis server tests.
Bug: https://github.com/dart-lang/sdk/issues/61524
Change-Id: I296f2fcd918b87bf2a1dd00256340759866c2423
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489241
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Nicholas Shahan <nshahan@google.com>
Reviewed-by: Michael Thomsen <mit@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Ben Konyi <bkonyi@google.com>
This reverts commit 3eb697c0af.
Reason for revert: Internal Google3 breakages
Original change's description:
> [flow analysis] Fix unsound type promotion in inner async/generator functions.
>
> An `await` expression or `yield` statement suspends the current
> function and allows other code in the same isolate to execute. In the
> case of nested functions, an `await` or `yield` in the inner function
> can allow the outer function to continue executing. That means that if
> the inner function promotes a local variable belonging to the outer
> function, then it isn't sound to carry that promotion past an `await`
> or `yield`.
>
> This change fixes the unsoundness by adding a flow analysis method
> `suspension`, which the shared type analysis logic uses to tell flow
> analysis that an `await` or `yield` has been found. The `suspension`
> method un-does the promotions of any variables that might be written
> to while the inner function is suspended.
>
> Fixes https://github.com/dart-lang/sdk/issues/62889.
>
> Change-Id: I77eaf997159819a7c50f44b67174d2aa6a6a6964
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499382
> Reviewed-by: Johnni Winther <johnniwinther@google.com>
> Commit-Queue: Paul Berry <paulberry@google.com>
> Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
> Reviewed-by: Bob Nystrom <rnystrom@google.com>
Change-Id: I187ba9a347394946ecc8749d35dc7914d271b90a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500540
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Bot-Commit: rubber-stamper@appspot.gserviceaccount.com <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Paul Berry <paulberry@google.com>
`List.unmodifiable` and `Map.unmodifiable` is as badly typed
as `List.from` and `Map.from`, but does not have a better-typed
`.of` constructor. This adds such, to give a migration target
when deprecating the badly typed constructors.
The `Future.delayed` with no second argument is also unsafely
typed, it fails if the type argument is not nullable.
The `Future.pause` creates `Future<void>` instead.
CoreLibraryReviewExempt: No new or platform specific behavior.
Change-Id: Iba101b3dc62f412003abd501fa042aca0ce63116
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499280
Commit-Queue: Lasse Nielsen <lrn@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Nate Bosch <nbosch@google.com>
An `await` expression or `yield` statement suspends the current
function and allows other code in the same isolate to execute. In the
case of nested functions, an `await` or `yield` in the inner function
can allow the outer function to continue executing. That means that if
the inner function promotes a local variable belonging to the outer
function, then it isn't sound to carry that promotion past an `await`
or `yield`.
This change fixes the unsoundness by adding a flow analysis method
`suspension`, which the shared type analysis logic uses to tell flow
analysis that an `await` or `yield` has been found. The `suspension`
method un-does the promotions of any variables that might be written
to while the inner function is suspended.
Fixes https://github.com/dart-lang/sdk/issues/62889.
Change-Id: I77eaf997159819a7c50f44b67174d2aa6a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/499382
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Coercion from `dynamic` to a non-top type has observable effects,
since it may throw an exception. Therefore it's important that any
tree manipulations that are performed as part of type inference (such
as hoisting of named arguments that precede unnamed ones) preserve the
order of coercions relative to expression evaluation.
Prior to this change, the following code:
f(n: e1, e2)
Would get transformed into:
let tmp = e1 in f(coerce(e2), n: coerce(tmp))
And so the coercion of e1 would not happen until after the evaluation
of e2.
With this change, the code is transformed into:
let tmp = coerce(e1) in f(coerce(e2), n: tmp)
Which (correctly) coerces e1 before evaluating e2.
Fixes https://github.com/dart-lang/sdk/issues/63150.
Change-Id: Iee33c162c7cc3a9b0a8b03bde211bf926a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/498980
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>