Commit Graph

6698 Commits

Author SHA1 Message Date
Nate Biggs 92ae8b61ec [dart2wasm] Fix switch statements that include a Type expression case.
'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>
2026-06-09 20:39:04 -07:00
Johnni Winther a90efd6794 [PrimaryConstructors] Add language test for issue 63506
This adds a regression test for issue 63506, testing that constant primary constructors with explicit super initializers compile correctly.

Change-Id: I4ca6e4115df41a343c0af289d1be04c9d96de9bf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/509280
Auto-Submit: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2026-06-04 09:52:40 -07:00
Konstantin Shcheglov 0e976d5ab1 Augment. Report recursiveInterfaceInheritance on the clause, if self-reference.
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>
2026-05-29 12:57:07 -07:00
Konstantin Shcheglov a898adf8b7 Augment. Support for abstract top-level variables and static fields.
Change-Id: Idf0ce319492c405dd06364cb6feb81e000a7c741
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/506606
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2026-05-28 09:19:15 -07:00
Lasse R.H. Nielsen 69e9d32e87 Retire 'privately-named-parameters' experiment flag.
Change-Id: I6526bd63be5f71090a3ea7f3c705778e7debf584
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/505340
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
Reviewed-by: Jonas Jensen <jonasfj@google.com>
2026-05-28 05:13:49 -07:00
Erik Ernst 3263555dc5 Start implementation of anonymous block methods
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>
2026-05-27 06:04:46 -07:00
Erik Ernst 945978f5c0 Change code generation for dart2js to enable capturing
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>
2026-05-21 04:22:30 -07:00
Simon Binder 58f9d88fb2 [dart2wasm, standalone] Migrate String
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>
2026-05-20 00:22:27 -07:00
Kallen Tu 2edcad4892 [tests] Primary constructors: Format and generate errors for all tests.
Cleaned up and formatted the tests, regenerated some errors where they were "unspecified", and removed the experiment flag enabling in each test.

Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: Ic5b652af660cbc4f71731b1547c7a58c7726faca
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/503500
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-05-18 10:00:37 -07:00
Konstantin Shcheglov 5ed538a532 Bug fix: implement missing diagnostic implementsSuperClassConstraint.
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>
2026-05-18 07:55:50 -07:00
Erik Ernst 96a4dd4c19 Modify property promotion: only this
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>
2026-05-13 00:08:24 -07:00
Erik Ernst 1b75e2701c Support promotion of instance variables with anonymous methods
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>
2026-05-07 05:39:13 -07:00
Konstantin Shcheglov 0a5604c223 Support for cross-file context messages in test_runner/.
Bug: https://github.com/dart-lang/sdk/issues/63318
Change-Id: Ie02aef92d9ab0e04ce864a85ed6071d5e4b5e14f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/500820
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2026-05-06 13:23:57 -07:00
Johnni Winther a782aed439 [cfe][PrimaryConstructors] Add AsyncModifier
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>
2026-05-06 01:35:05 -07:00
Kallen Tu 8bfb683892 Enable 'primary-constructors' feature flag.
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>
2026-05-04 15:09:49 -07:00
Paul Berry 9dfa6738c9 Revert "[flow analysis] Fix unsound type promotion in inner async/generator functions."
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>
2026-05-04 10:37:11 -07:00
Paul Berry 3eb697c0af [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>
2026-05-01 07:16:25 -07:00
Paul Berry 07b9707d96 [front end] Perform hoisting after coercion.
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>
2026-04-30 11:05:39 -07:00
Nate Biggs 3d2d6492c1 Add 'external-effect' pragma support to all the backends.
Call sites targeting a procedure annotated with `external-effect` will
not produce any code, including the argument which will not be
evaluated.

However, the single parameter will be treated as 'live' for the purposes
of any global analysis the backends do. This is useful for things like
protobuf shaking where a user may want to retain certain protobuf
messages without actually emitting the code that retains those messages.

Today this functionality is available internally in the vm and wasm SDK
libraries. dart2js has similar functionality represented via the
opaqueTrue and opaqueFalse booleans (which will cause conditional
branches to get shaken after analysis). This will replace dart2js's
opaque(True/False).

This also adds validation to the frontend to ensure a method annotated
with 'external-effect' is well-formed.

Change-Id: If1c4096673e655c58fe7638840a16125003e7809
Tested: Backend tests for codegen were added. A frontend test was added for the validation. A language test was added to confirm the behavior.
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/476020
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2026-04-27 09:42:38 -07:00
Simon Binder 03fd5927a4 [dart2wasm, standalone]: Avoid importing js-string constants
dart2wasm imports strings as globals for which JavaScript engines would
provide the respective values. The standalone target needs to support
all WebAssembly runtimes, so it can't rely on this mechanism.

Instead, this imports functions to convert a WebAssembly arrays of char
codes or ASCII bytes into a string. For now, these functions have to
return JS strings since the rest of the SDK relies on that. In the
future, embedders would be able to return any string implementation as
an externref.

Because calling host functions is invalid in constant contexts, string
constants can't be regular globals. For now, this uses the default
non-eager constant implementation with one initialization function per
string constant. Eventually, we should probably initialize these
strings in a WASM start function instead.

TEST=pkg/dart2wasm/test/standalone_test.dart
Change-Id: I93b7c3846fbe99daa8ffa31e452f62672b61ce4b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495020
Reviewed-by: Nate Biggs <natebiggs@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Nate Biggs <natebiggs@google.com>
2026-04-24 10:49:11 -07:00
Kallen Tu 77cf3047a3 Dot Shorthands: Const selector chains.
I changed the parsing of const dot shorthands to parse the entire selector chain in `parsePrecedenceExpression` rather than parsing them in `parseConstExpression`. We were originally parsing the initial expression before the `.` and only flagging that as a dot shorthand which prevented any chaining on const constructors. Const expressions with chained methods/property accesses were not being flagged as a dot shorthand so we weren’t saving the context type properly which led to producing the “unknown context type” error.

Before:
```
class C {
  const new someConstCtor();
  C method() => this;
}

C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor
// (const .someConstCtor) is handled as a dot shorthand, context is
// saved on only this AST and not the outer chain.
// Then we parse the rest of the selector chain (.method())
//
// Error: No context type for (const .someConstCtor.method())
```

After:
```
class C {
  const new someConstCtor();
  C method() => this;
}

C c = const .someConstCtor.method();
// (const .someConstCtor) is parsed and handled as a const constructor.
// Then we parse the rest of the selector chain (.method())
// (const .someConstCtor.method()) is handled as a dot shorthand, context is saved for this outer node.
//
// OK. No error because we are able to retrieve the type for the
// entire dot shorthand chain.
```

Fixes: https://github.com/dart-lang/sdk/issues/63119
Change-Id: I3308d8eb7ce101466be257aba6b5448921bff136
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495560
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-04-24 10:40:26 -07:00
Paul Berry 8d59e904e4 [anonymous methods] Test private field promotion.
To work properly with anonymous methods, the private field promotion
logic in flow analysis will have to be updated so that it understands
that `this` refers to a different object inside of an anonymous
method.

This CL adds new language tests to validate that this logic has been
properly updated.

Change-Id: I4ad2c289c5b39bb7397e68eff74324226a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/496720
Commit-Queue: Paul Berry <paulberry@google.com>
Auto-Submit: Paul Berry <paulberry@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
2026-04-22 10:19:04 -07:00
Paul Berry 46e2cfe3fd [anonymous methods] Test that super can't be used in parameterless anonymous methods.
Change-Id: Icf5ccff095e42a6e8c151b31c741aec96a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/497061
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
2026-04-22 07:19:04 -07:00
Erik Ernst e05ce41c0d Add anonymous => method related implementation in the CFE
This CL adds an implementation of anonymous `=>` methods in the CFE
which is sufficiently complete to handle the existing test cases in
language/anonymous_methods/expression.

Coverage is handled by adding magic comments to ignore the fact that new
code is not covered by existing testcases. This will be settled in a
separate CL.

To keep the failures visible, the failures in configurations
dart2js-hostasserts-linux-d8-try, dart2js-linux-chrome-try,
dart2js-minified-linux-d8-try, and ddc-linux-chrome-try have not been
approved. It seems likely to me that those are bugs in dart2js and in
DDC.

Change-Id: Ia70fedd4de6166d6a3bf8a108f49728b6e16c9f6
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494440
Commit-Queue: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2026-04-21 02:09:41 -07:00
Konstantin Shcheglov 6cd3938741 Breaking changes for analyzer 13.0.0
https://github.com/dart-lang/sdk/issues/62799
https://github.com/dart-lang/sdk/issues/62944
https://github.com/dart-lang/sdk/issues/63002
https://github.com/dart-lang/sdk/issues/62970

Looks mostly green in google3: https://fusion2.corp.google.com/presubmit/901021300/OCL:901021300:BASE:901308428:1776439417713:37cd1695

Change-Id: I44754a48f66a0b58851d7c20fcfa61f7fb1b555a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/488624
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
2026-04-17 23:06:25 -07:00
Kallen Tu 1c7332ec86 [tests] Primary constructors: Enums have implicitly const constructors.
Added a single test for this new change.
Tested with new and old constructor syntax.

Bug: https://github.com/dart-lang/language/issues/4494
Change-Id: I8cda70398fb1d7de17f41fc541edaf8f16490a8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/495580
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-04-16 11:56:05 -07:00
Johnni Winther 1d40001a98 [cfe][PrimaryConstructors] Don't remove const modifier
This stops the practice of removing the const modifier from const constructors with a body. Since primary constructor introduces more complex scenarios of this problem space, retaining the constness seems to have better results in terms of cascading errors. In particular, not reporting that a non-const constructor cannot be invoked when it is actual a const (alas erroneous) constructor.

Change-Id: I33b3982ec0fce89946f8700f98bf08161d930d36
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494120
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2026-04-15 03:08:56 -07:00
Paul Berry 25bb8ce922 Add language tests for issues 33298 and 56666.
Yesterday I discovered some code in the front end type inference
engine that I didn't expect: logic that added constraints to type
inference based on the result of applying type coercions. To figure
out why it was necessary, I disabled it and ran the code through
trybots. It turns out that it's needed to prevent the following
issues:
- https://github.com/dart-lang/sdk/issues/33298
- https://github.com/dart-lang/sdk/issues/56666

Fortunately, we had regression tests for these issues:
- `pkg/front_end/testcases/general/bug33298.dart`
- `pkg/front_end/testcases/general/issue56666.dart`

Unfortunately, those regression tests are front-end specific, meaning
we didn't have any coverage for the analyzer.

This CL adds coverage for the analyzer by replicating the regression
tests in `tests/language`.

Change-Id: Ia53b3c898549e991d6685a414d177a466a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494563
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Lasse Nielsen <lrn@google.com>
2026-04-13 09:30:21 -07:00
Erik Ernst 56df2ae167 Adjust flow analysis to handle break/continue in an anonymous method
This CL changes the flow analysis slightly such that the analyzer is
able to handle a `break;`, `break L;`, `continue;`, or `continue L;`
that occurs in the body of an anonymous method. It adds a test for a few
situations where this feature is used.

Change-Id: I5b065a6ad96e346502fd071d1547ccd143f37e80
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491800
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
2026-04-13 01:06:01 -07:00
Paul Berry 3d56c6bb91 Test yield* when the return context is Iterable<_>.
This covers a test case that I forgot to include in
https://dart-review.googlesource.com/c/sdk/+/491706. As with that CL,
this test is solely intended to ensure that the current behavior is
adequately tested, so that we will avoid inadvertently changing it
while doing refactors.

Changes to the specification are being contemplated; see
https://github.com/dart-lang/language/pull/4673 and
https://github.com/dart-lang/language/issues/4672.

Change-Id: I5a21bfc2555857542d0dc02b757672a36a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/492660
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
2026-04-09 15:01:17 -07:00
Konstantin Shcheglov e1404d8539 Split mixinClassDeclarationWithClause and mixinModifierMixinApplicationClassWithMultipleMixins from mixinClassDeclarationExtendsNotObject.
Report dedicated diagnostics for mixin classes that use a `with` clause
and for mixin application classes that use multiple mixins, instead of
folding both cases into `mixinClassDeclarationExtendsNotObject`.

This makes the reported error match the actual invalid construct. A
`mixin class` with a `with` clause does not have the same problem as a
`mixin class` that extends a non-`Object` superclass, and a mixin
application with multiple mixins is a separate restriction again.

Update the error verifier, diagnostic definitions, messages, and fix
status entries to use the new codes. Also guard `RemoveExtendsClause` so
it only offers a fix when an actual extends clause is present, avoiding
a bogus fix for diagnostics that are now reported on `with` clauses
instead.

Consolidate the diagnostic tests under a single mixin class declaration
test file and update expectations to use the more precise error codes.

The original impetus for this change was a crash in RemoveExtendsClause
quick fix.

Change-Id: I937276f37deb293ca1fecab3ff838ace45af2ec4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/493865
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
2026-04-09 15:01:11 -07:00
Konstantin Shcheglov eb1b8ea844 FixCrash. When a type parameter is referenced in static context, instantiate it to InvalidType.
When a class type parameter is referenced from a static member, the
analyzer could still instantiate it as an ordinary type parameter during
resolution and summary building. That produced inconsistent invalid
states, led to follow-on type errors, and could crash later stages that
expected a real type or a consistently invalid one.

Teach `ScopeContext` to track whether resolution is inside a static
member and use that information when instantiating type parameters. If
the referenced type parameter belongs to the enclosing instance context,
resolve it to `InvalidType` instead.

Route both `NamedTypeResolver` and `reference_resolver` through this
shared helper so fields, methods, and other named type paths handle
static references consistently. This keeps the original
`TYPE_PARAMETER_REFERENCED_BY_STATIC` diagnostic while preventing
spurious assignment and return-type errors from cascading afterward.

Bug: https://github.com/dart-lang/sdk/issues/60745
Change-Id: Ib9e685b967de5baa8a26b542be630c9fb0d6a96b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/494040
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2026-04-09 09:34:54 -07:00
Kallen Tu c0961ff71b [tests] Primary constructors - Mixin class, const constructor bodies tests
Tests the following:
- A compile-time error occurs if a class, mixin class, enum, or
extension type has a constant primary constructor which has a body part
that has a body.
- A compile-time error occurs if a mixin class declaration has a primary
constructor which is not trivial, that is, it declares one or more
parameters, or it has a body part that has an initializer list or
a body.

Spec changes:
https://github.com/dart-lang/language/commit/e2cbe29ca23431b9d76faba4b5ead520709689cd
https://github.com/dart-lang/language/commit/9d00e024647fea00993be9c111f52528f8510206

Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: If19a96cc275d502b2bdaf3924c699b5a742a1557
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/492661
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-04-08 15:12:21 -07:00
Erik Ernst e7debdf978 Add anonymous method error tests
Change-Id: I48de987b60b86a7fb52a52e75d79eaa754d5cc6c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/492160
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
2026-04-08 02:45:57 -07:00
Johnni Winther 575553bbd2 [cfe][PrimaryConstructors] Update test expectations
This updates primary constructor tests to expect the current CFE output.

Change-Id: Ie9cd3cd6d6954642fc9e0a2f7dcd527e1fc711dd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/493241
Reviewed-by: Kallen Tu <kallentu@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2026-04-08 02:05:38 -07:00
Konstantin Shcheglov cd7e32217f DeCo. Report const_primary_constructor_with_block_body,
const_primary_constructor_with_expression_body, primary_constructor_body_with_expression_body, primary_constructor_body_with_modifier

Bug: https://github.com/dart-lang/language/pull/4671
Change-Id: I4eb8326a2f01ee7c3a47f08fe897eb702ba994d5
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/492281
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
2026-04-02 16:05:20 -07:00
Paul Berry 6cc1bdb1ad Add language tests of yield* downwards inference.
These tests cover the behaviors mentioned in
https://github.com/dart-lang/language/issues/4672.

Long term, I'm not certain whether these are the behaviors we
want. But considering that these are the behaviors we have, it seems
reasonable to test them to avoid regressions.

Paves the way for a follow-up CL that will refactor some of the
analyzer and front end logic that handles yield statements.

Change-Id: I6af8eb67dac588d90ed95e2536184c4a6a6a6964
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491706
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Paul Berry <paulberry@google.com>
2026-04-02 11:15:32 -07:00
Konstantin Shcheglov d53518cba5 Issue 62663. Split mixin_class_declares_constructor into class_used_as_mixin_declares_generative_constructor and mixin_class_declares_non_trivial_generative_constructor.
Bug: https://github.com/dart-lang/sdk/issues/62663
Change-Id: I7096923f139ed91451056066aa68965f1b821c5c
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/491925
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2026-04-01 15:20:26 -07:00
Johnni Winther 4cfd3da965 [cfe][PrimaryConstructors] Update reporting for mixin class with initializer/constructor body
This update the position used for reporting a mixin class primary constructor with a primary constructor by declaration with initializers or an explicit body. Since mixin classes can have simple constructors, it makes more sense to report the error on the offending syntax than on the primary constructor itself.

The CL also updates the offset used for field initializers to the field name rather than the `=`. This align the offset with what is used for property sets.

Change-Id: Id5ccd55536b2c3b9d9336d2854772c1bcc5a175a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/490800
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
2026-04-01 01:17:28 -07:00
Konstantin Shcheglov 5ef56befcb Variance. Report errors on INOUT and OUT built-in identifiers when Feature.variance is enabled.
Change-Id: I4788439bea71532d2c52b715543f7deaeacdf519
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489982
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
2026-03-24 13:29:17 -07:00
David Morgan f58991b35b Remove augmentation libraries test as it's out of date with the spec.
Change-Id: I6b85558dd3e135612ad45b07aa74e8e85e3321a2
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/490102
Commit-Queue: Morgan :) <davidmorgan@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
2026-03-24 08:59:23 -07:00
David Morgan 9ad39ca351 Revert "[test_runner] Support static error test expectations in augmentation libraries."
This reverts commit 261e16e822.

Reason for revert: The feature no longer specifies "augmentations libraries", see 1.22 in the changelog. https://github.com/dart-lang/language/blob/main/working/augmentations/feature-specification.md

Original change's description:
> [test_runner] Support static error test expectations in augmentation libraries.
>
> R=eernst@google.com
>
> Change-Id: I52fd157be6ba561f571170ce393d80820b2744dc
> Bug: https://github.com/dart-lang/sdk/issues/44990
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/356401
> Reviewed-by: Erik Ernst <eernst@google.com>
> Auto-Submit: Morgan :) <davidmorgan@google.com>
> Commit-Queue: Morgan :) <davidmorgan@google.com>

Bug: https://github.com/dart-lang/sdk/issues/44990
Change-Id: Ifbba5d7f7d2720bac3dc638ca00c96246b6fef95
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/490100
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Morgan :) <davidmorgan@google.com>
Reviewed-by: Ivan Inozemtsev <iinozemtsev@google.com>
2026-03-24 05:22:10 -07:00
Kallen Tu 7481d41941 [tests] Primary constructors - Add const initializer and body tests.
Tests for the spec change in https://github.com/dart-lang/language/pull/4655.

- An identifier expression denoting a parameter of a constant primary
constructor that occurs in the initializer list of the body part of the
primary constructor, or in an initializing expression of a non-late
instance variable declaration, is potentially constant.
- A compile-time error occurs if a class, mixin class, enum, or
extension type declaration has a constant generative constructor, and a
non-late instance variable declaration in the body of the declaration
has an initializing expression which is not potentially constant.
- A compile-time error also occurs if the body of a declaration contains
a body part for the primary constructor, and it has an initializer list,
and the initializer list contains an expression which is not potentially
constant.
- A compile-time error occurs if the result of substituting actual
arguments of the constructor invocation into one of the above mentioned
initializing expressions or initializer list elements yields an
expression which is not constant.

Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: I8f9d5d49ab48f6cd07ad005b9483e21ef190f324
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489543
Commit-Queue: Kallen Tu <kallentu@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
2026-03-23 13:59:04 -07:00
Lasse R.H. Nielsen 56505e0575 Stop using Match.group.
The `Match.operator[]` does the same thing and is
generally recommended (and shorter).
(I want to deprecate `group` and `groups`)

Tested: Refactoring.
CoreLibraryReviewExempt: Calling equivalent function.
Change-Id: I4c758968ae622fe16b7322be1b29b05b91e7fcd9
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489021
Reviewed-by: Paul Berry <paulberry@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
Commit-Queue: Lasse Nielsen <lrn@google.com>
2026-03-20 09:09:46 -07:00
Erik Ernst 9d2e96b25f Take steps to support anonymous block bodies
This CL adds support for anonymous block bodies (as in `e.{...}`) by
generalizing the flow analysis to handle begin/end of anonymous block
bodies and treating them similarly to labeled statements (and treating
`return` statements using `handleBreak`). It generalizes `handleBreak`
and the internal make `_StatementToContext` to handle `Node` keys rather
than just `Statement` keys, such that an anonymous block body can be the
context. It adds a `bodyContext` instance variable to
`AnonymousBodyImpl` to be used during flow analysis of anonymous block
bodies. `BodyInferenceContext` gets a new factory constructor in order
to allow an anonymous block body to be the context. Finally,
`ErrorVerifier` is generalized to handle the case where a return
statement is returning from an anonymous block body.

Change-Id: I04bc3c852611dbefb885afce655dc00054709fb7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/482786
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Samuel Rawlins <srawlins@google.com>
Reviewed-by: Paul Berry <paulberry@google.com>
Commit-Queue: Erik Ernst <eernst@google.com>
2026-03-13 08:54:16 -07:00
Kallen Tu 39870102e6 [tests] Primary constructors - More cases for empty body test.
From Lasse's comment in
https://dart-review.googlesource.com/c/sdk/+/486525. Added many more
combinations of extends, implements and mixin applications to
`empty_body_test.dart`.

Bug: https://github.com/dart-lang/sdk/issues/61687
Change-Id: Ie26c7661d6505d21c2f457b285f1ef1b88b8e6ac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486863
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-03-11 16:07:00 -07:00
Kallen Tu d87e8f866c [tests] Add test for explicit class body on mixin applications.
Adding in an extra test just to make sure this isn't
possible. Don't know if we already have a test for this,
but I couldn't find anything.

Change-Id: Id2ce089e070cc139389e805f1b8b7f987a438bfd
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486525
Reviewed-by: Lasse Nielsen <lrn@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-03-10 14:58:45 -07:00
Johnni Winther a6bc2c3608 [cfe][PrimaryConstructors] Use MemberLookupResult for redirecting initializers
This uses MemberLookupResult instead of Builder as the result for BodyBuilderContext.lookupConstructor. This allows for a more precise handling of error cases and avoids reporting cascading error in case of duplicate constructors.

Change-Id: I465747883af594870cb0663e80a188e6dd1b552b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486202
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
2026-03-10 02:55:53 -07:00
Kallen Tu dde4b2475d [tests] Variance - out and inout are built-in identifiers.
Updating language tests to mark `inout` and `out` as built-in identifiers. They should produce a compile-time error if used as a type name.

Bug: https://github.com/dart-lang/language/issues/524

Change-Id: Ibdefb1090ecdd64c2bee4dcb7cc5ec8708455fcf
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486341
Reviewed-by: Erik Ernst <eernst@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
2026-03-09 13:19:16 -07:00
Johnni Winther 988cd0f9b7 [cfe][PrimaryConstructors] Add isRedirecting/SuperInitializer flags to InvalidInitializer
This adds isRedirectingInitializer and isSuperInitializer to the Initializer hierarchy and adds flags to InvalidInitializer to signal when the InvalidInitializer should be taking as a redirecting or super initializer. This allows us to avoid miscatergorizing such declarations when they are erroneous.

Part of #61700

TEST=existing

Change-Id: If0fabbda10b72304999a5380fce74f9e8fa91ca4
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/486180
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Chloe Stefantsova <cstefantsova@google.com>
2026-03-09 03:36:55 -07:00