[cfe][PrimaryConstructors] Update primary constructor parameter scope

This updates the primary constructor parameter scope to be nested within the body scope of the enclosing declaration instead of the type parameter scope of the enclosing declaration.

Part of #61700

Change-Id: I8be1e7c4c9b81d1f4f8e6423d6c241b1222568b0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/479000
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Erik Ernst <eernst@google.com>
This commit is contained in:
Johnni Winther
2026-02-10 00:40:53 -08:00
committed by Commit Queue
parent a4be844171
commit 1a88f3b7ce
27 changed files with 1116 additions and 1 deletions
@@ -22,7 +22,10 @@ abstract class DeclarationFragmentImpl implements DeclarationFragment {
final LookupScope enclosingScope;
final LookupScope typeParameterScope;
@override
final DeclarationBuilderScope bodyScope;
final List<Fragment> _fragments = [];
@override
@@ -146,4 +146,7 @@ abstract interface class DeclarationFragment {
/// Type parameters declared on this declaration.
List<TypeParameterFragment>? get typeParameters;
/// Returns the body scope for this declaration.
LookupScope get bodyScope;
}
@@ -1405,6 +1405,10 @@ class FragmentFactoryImpl implements FragmentFactory {
DeclarationFragmentImpl enclosingDeclaration =
_declarationFragments.current;
// The name space is, while initially empty, created to support the lowering
// of extension (type) constructors which clone the extension (type) type
// parameters into the nominal parameter name space of the primary
// constructor.
NominalParameterNameSpace nominalParameterNameSpace =
new NominalParameterNameSpace();
_nominalParameterNameSpaces.push(nominalParameterNameSpace);
@@ -1412,7 +1416,15 @@ class FragmentFactoryImpl implements FragmentFactory {
new TypeScope(
TypeScopeKind.memberTypeParameters,
new NominalParameterScope(
_typeScopes.current.lookupScope,
libraryFeatures.primaryConstructors.isEnabled
// Contrary to most other declarations, the type parameter scope
// of a primary constructor is _not_ the current type scope, which
// is the type parameter scope of the enclosing declaration, but
// instead the body scope of the enclosing declaration.
? enclosingDeclaration.bodyScope
// Prior to the primary constructors feature, the enclosing scope
// was the current type scope.
: _typeScopes.current.lookupScope,
nominalParameterNameSpace,
),
_typeScopes.current,
@@ -364,6 +364,7 @@ containment
contextually
continuations
contra
contrary
contribute
conveniently
convention
@@ -0,0 +1,57 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class C1<T> {
T b;
final T c;
T d;
T e;
T f;
Type g = T;
C1(T a, this.b, this.c) : d = a, e = b, f = c, g = T {
print(T);
}
}
class C2<T>(T a, var T b, final T c) {
T d = a;
T e = b;
T f = c;
Type g = T;
this {
print(T);
}
}
enum E1<T> {
a<int>(0, 1);
final T b;
final T c;
final T d;
final Type f;
const E1(T a, this.b) : c = a, d = b, f = T;
}
enum E2<T>(T a, final T b) {
a<int>(0, 1);
final T d = a;
final T e = b;
final Type f = T;
}
extension type ET1<T>(T a) {
ET1.other(this.a) {
print(T);
}
}
extension type ET2<T>(T a) {
this {
print(T);
}
}
@@ -0,0 +1,109 @@
library;
import self as self;
import "dart:core" as core;
class C1<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C1::T% b;
final field self::C1::T% c;
covariant-by-class field self::C1::T% d;
covariant-by-class field self::C1::T% e;
covariant-by-class field self::C1::T% f;
field core::Type g = self::C1::T%;
constructor •(self::C1::T% a, self::C1::T% b, self::C1::T% c) → self::C1<self::C1::T%>
: self::C1::b = b, self::C1::c = c, self::C1::d = a, self::C1::e = b, self::C1::f = c, self::C1::g = self::C1::T%, super core::Object::•() {
core::print(self::C1::T%);
}
}
class C2<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C2::T% b;
final field self::C2::T% c;
covariant-by-class field self::C2::T% d;
covariant-by-class field self::C2::T% e;
covariant-by-class field self::C2::T% f;
field core::Type g;
constructor •(self::C2::T% a, self::C2::T% b, final self::C2::T% c) → self::C2<self::C2::T%>
: self::C2::d = a, self::C2::e = b, self::C2::f = c, self::C2::g = self::C2::T%, self::C2::b = b, self::C2::c = c, super core::Object::•() {
core::print(self::C2::T%);
}
}
class E1<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1<core::int> a = #C5;
final field self::E1::T% b;
final field self::E1::T% c;
final field self::E1::T% d;
final field core::Type f;
static const field core::List<self::E1<dynamic>> values = #C6;
const constructor •(core::int #index, core::String #name, self::E1::T% a, self::E1::T% b) → self::E1<self::E1::T%>
: self::E1::b = b, self::E1::c = a, self::E1::d = b, self::E1::f = self::E1::T%, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
final field self::E2::T% b;
enum-element static const field self::E2<core::int> a = #C7;
final field self::E2::T% d;
final field self::E2::T% e;
final field core::Type f;
static const field core::List<self::E2<dynamic>> values = #C8;
const constructor •(core::int #index, core::String #name, self::E2::T% a, final self::E2::T% b) → self::E2<self::E2::T%>
: self::E2::d = a, self::E2::e = b, self::E2::f = self::E2::T%, self::E2::b = b, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor other = self::ET1|constructor#other;
constructor tearoff other = self::ET1|constructor#_#other#tearOff;
}
extension type ET2<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#<T extends core::Object? = dynamic>(self::ET1|constructor#::T% a) → self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ #this = a;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#new#tearOff::T% a) → self::ET1<self::ET1|constructor#_#new#tearOff::T%>% /* erasure=self::ET1|constructor#_#new#tearOff::T%, declared=! */
return self::ET1|constructor#<self::ET1|constructor#_#new#tearOff::T%>(a);
static extension-type-member method ET1|constructor#other<T extends core::Object? = dynamic>(self::ET1|constructor#other::T% a) → self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ #this = a;
{
core::print(self::ET1|constructor#other::T%);
}
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#other#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#other#tearOff::T% a) → self::ET1<self::ET1|constructor#_#other#tearOff::T%>% /* erasure=self::ET1|constructor#_#other#tearOff::T%, declared=! */
return self::ET1|constructor#other<self::ET1|constructor#_#other#tearOff::T%>(a);
static extension-type-member method ET2|constructor#<T extends core::Object? = dynamic>(self::ET2|constructor#::T% a) → self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ {
lowered final self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ #this = a;
{
core::print(self::ET2|constructor#::T%);
}
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET2|constructor#_#new#tearOff::T% a) → self::ET2<self::ET2|constructor#_#new#tearOff::T%>% /* erasure=self::ET2|constructor#_#new#tearOff::T%, declared=! */
return self::ET2|constructor#<self::ET2|constructor#_#new#tearOff::T%>(a);
constants {
#C1 = 1
#C2 = 0
#C3 = TypeLiteralConstant(core::int)
#C4 = "a"
#C5 = self::E1<core::int> {b:#C1, c:#C2, d:#C1, f:#C3, index:#C2, _name:#C4}
#C6 = <self::E1<dynamic>>[#C5]
#C7 = self::E2<core::int> {b:#C1, d:#C2, e:#C1, f:#C3, index:#C2, _name:#C4}
#C8 = <self::E2<dynamic>>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///generic_primary_constructor.dart:
- E1. (from org-dartlang-testcase:///generic_primary_constructor.dart:37:9)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///generic_primary_constructor.dart:40:11)
@@ -0,0 +1,109 @@
library;
import self as self;
import "dart:core" as core;
class C1<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C1::T% b;
final field self::C1::T% c;
covariant-by-class field self::C1::T% d;
covariant-by-class field self::C1::T% e;
covariant-by-class field self::C1::T% f;
field core::Type g = self::C1::T%;
constructor •(self::C1::T% a, self::C1::T% b, self::C1::T% c) → self::C1<self::C1::T%>
: self::C1::b = b, self::C1::c = c, self::C1::d = a, self::C1::e = b, self::C1::f = c, self::C1::g = self::C1::T%, super core::Object::•() {
core::print(self::C1::T%);
}
}
class C2<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C2::T% b;
final field self::C2::T% c;
covariant-by-class field self::C2::T% d;
covariant-by-class field self::C2::T% e;
covariant-by-class field self::C2::T% f;
field core::Type g;
constructor •(self::C2::T% a, self::C2::T% b, final self::C2::T% c) → self::C2<self::C2::T%>
: self::C2::d = a, self::C2::e = b, self::C2::f = c, self::C2::g = self::C2::T%, self::C2::b = b, self::C2::c = c, super core::Object::•() {
core::print(self::C2::T%);
}
}
class E1<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1<core::int> a = #C5;
final field self::E1::T% b;
final field self::E1::T% c;
final field self::E1::T% d;
final field core::Type f;
static const field core::List<self::E1<dynamic>> values = #C6;
const constructor •(core::int #index, core::String #name, self::E1::T% a, self::E1::T% b) → self::E1<self::E1::T%>
: self::E1::b = b, self::E1::c = a, self::E1::d = b, self::E1::f = self::E1::T%, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
final field self::E2::T% b;
enum-element static const field self::E2<core::int> a = #C7;
final field self::E2::T% d;
final field self::E2::T% e;
final field core::Type f;
static const field core::List<self::E2<dynamic>> values = #C8;
const constructor •(core::int #index, core::String #name, self::E2::T% a, final self::E2::T% b) → self::E2<self::E2::T%>
: self::E2::d = a, self::E2::e = b, self::E2::f = self::E2::T%, self::E2::b = b, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor other = self::ET1|constructor#other;
constructor tearoff other = self::ET1|constructor#_#other#tearOff;
}
extension type ET2<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#<T extends core::Object? = dynamic>(self::ET1|constructor#::T% a) → self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ #this = a;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#new#tearOff::T% a) → self::ET1<self::ET1|constructor#_#new#tearOff::T%>% /* erasure=self::ET1|constructor#_#new#tearOff::T%, declared=! */
return self::ET1|constructor#<self::ET1|constructor#_#new#tearOff::T%>(a);
static extension-type-member method ET1|constructor#other<T extends core::Object? = dynamic>(self::ET1|constructor#other::T% a) → self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ #this = a;
{
core::print(self::ET1|constructor#other::T%);
}
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#other#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#other#tearOff::T% a) → self::ET1<self::ET1|constructor#_#other#tearOff::T%>% /* erasure=self::ET1|constructor#_#other#tearOff::T%, declared=! */
return self::ET1|constructor#other<self::ET1|constructor#_#other#tearOff::T%>(a);
static extension-type-member method ET2|constructor#<T extends core::Object? = dynamic>(self::ET2|constructor#::T% a) → self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ {
lowered final self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ #this = a;
{
core::print(self::ET2|constructor#::T%);
}
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET2|constructor#_#new#tearOff::T% a) → self::ET2<self::ET2|constructor#_#new#tearOff::T%>% /* erasure=self::ET2|constructor#_#new#tearOff::T%, declared=! */
return self::ET2|constructor#<self::ET2|constructor#_#new#tearOff::T%>(a);
constants {
#C1 = 1
#C2 = 0
#C3 = TypeLiteralConstant(core::int)
#C4 = "a"
#C5 = self::E1<core::int> {b:#C1, c:#C2, d:#C1, f:#C3, index:#C2, _name:#C4}
#C6 = <self::E1<dynamic>>[#C5]
#C7 = self::E2<core::int> {b:#C1, d:#C2, e:#C1, f:#C3, index:#C2, _name:#C4}
#C8 = <self::E2<dynamic>>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///generic_primary_constructor.dart:
- E1. (from org-dartlang-testcase:///generic_primary_constructor.dart:37:9)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///generic_primary_constructor.dart:40:11)
@@ -0,0 +1,82 @@
library;
import self as self;
import "dart:core" as core;
class C1<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C1::T% b;
final field self::C1::T% c;
covariant-by-class field self::C1::T% d;
covariant-by-class field self::C1::T% e;
covariant-by-class field self::C1::T% f;
field core::Type g;
constructor •(self::C1::T% a, self::C1::T% b, self::C1::T% c) → self::C1<self::C1::T%>
;
}
class C2<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C2::T% b;
final field self::C2::T% c;
covariant-by-class field self::C2::T% d;
covariant-by-class field self::C2::T% e;
covariant-by-class field self::C2::T% f;
field core::Type g;
constructor •(self::C2::T% a, self::C2::T% b, final self::C2::T% c) → self::C2<self::C2::T%>
;
}
class E1<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1<core::int> a = const self::E1::•<core::int>(0, "a", 0, 1);
final field self::E1::T% b;
final field self::E1::T% c;
final field self::E1::T% d;
final field core::Type f;
static const field core::List<self::E1<dynamic>> values = const <self::E1<dynamic>>[self::E1::a];
const constructor •(core::int #index, core::String #name, self::E1::T% a, self::E1::T% b) → self::E1<self::E1::T%>
: self::E1::b = b, self::E1::c = a, self::E1::d = b, self::E1::f = self::E1::T%, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
final field self::E2::T% b;
enum-element static const field self::E2<core::int> a = const self::E2::•<core::int>(0, "a", 0, 1);
final field self::E2::T% d;
final field self::E2::T% e;
final field core::Type f;
static const field core::List<self::E2<dynamic>> values = const <self::E2<dynamic>>[self::E2::a];
const constructor •(core::int #index, core::String #name, self::E2::T% a, final self::E2::T% b) → self::E2<self::E2::T%>
: self::E2::b = b, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor other = self::ET1|constructor#other;
constructor tearoff other = self::ET1|constructor#_#other#tearOff;
}
extension type ET2<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#<T extends core::Object? = dynamic>(self::ET1|constructor#::T% a) → self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#new#tearOff::T% a) → self::ET1<self::ET1|constructor#_#new#tearOff::T%>% /* erasure=self::ET1|constructor#_#new#tearOff::T%, declared=! */
return self::ET1|constructor#<self::ET1|constructor#_#new#tearOff::T%>(a);
static extension-type-member method ET1|constructor#other<T extends core::Object? = dynamic>(self::ET1|constructor#other::T% a) → self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#other#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#other#tearOff::T% a) → self::ET1<self::ET1|constructor#_#other#tearOff::T%>% /* erasure=self::ET1|constructor#_#other#tearOff::T%, declared=! */
return self::ET1|constructor#other<self::ET1|constructor#_#other#tearOff::T%>(a);
static extension-type-member method ET2|constructor#<T extends core::Object? = dynamic>(self::ET2|constructor#::T% a) → self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET2|constructor#_#new#tearOff::T% a) → self::ET2<self::ET2|constructor#_#new#tearOff::T%>% /* erasure=self::ET2|constructor#_#new#tearOff::T%, declared=! */
return self::ET2|constructor#<self::ET2|constructor#_#new#tearOff::T%>(a);
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///generic_primary_constructor.dart:30:3 -> InstanceConstant(const E1<int>{E1.b: 1, E1.c: 0, E1.d: 1, E1.f: int, _Enum.index: 0, _Enum._name: "a"})
Evaluated: ListLiteral @ org-dartlang-testcase:///generic_primary_constructor.dart:29:6 -> ListConstant(const <E1<dynamic>>[const E1<int>{E1.b: 1, E1.c: 0, E1.d: 1, E1.f: int, _Enum.index: 0, _Enum._name: "a"}])
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///generic_primary_constructor.dart:41:3 -> InstanceConstant(const E2<int>{E2.b: 1, E2.d: null, E2.e: null, E2.f: null, _Enum.index: 0, _Enum._name: "a"})
Evaluated: ListLiteral @ org-dartlang-testcase:///generic_primary_constructor.dart:40:6 -> ListConstant(const <E2<dynamic>>[const E2<int>{E2.b: 1, E2.d: null, E2.e: null, E2.f: null, _Enum.index: 0, _Enum._name: "a"}])
Extra constant evaluation: evaluated: 25, effectively constant: 4
@@ -0,0 +1,109 @@
library;
import self as self;
import "dart:core" as core;
class C1<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C1::T% b;
final field self::C1::T% c;
covariant-by-class field self::C1::T% d;
covariant-by-class field self::C1::T% e;
covariant-by-class field self::C1::T% f;
field core::Type g = self::C1::T%;
constructor •(self::C1::T% a, self::C1::T% b, self::C1::T% c) → self::C1<self::C1::T%>
: self::C1::b = b, self::C1::c = c, self::C1::d = a, self::C1::e = b, self::C1::f = c, self::C1::g = self::C1::T%, super core::Object::•() {
core::print(self::C1::T%);
}
}
class C2<T extends core::Object? = dynamic> extends core::Object {
covariant-by-class field self::C2::T% b;
final field self::C2::T% c;
covariant-by-class field self::C2::T% d;
covariant-by-class field self::C2::T% e;
covariant-by-class field self::C2::T% f;
field core::Type g;
constructor •(self::C2::T% a, self::C2::T% b, final self::C2::T% c) → self::C2<self::C2::T%>
: self::C2::d = a, self::C2::e = b, self::C2::f = c, self::C2::g = self::C2::T%, self::C2::b = b, self::C2::c = c, super core::Object::•() {
core::print(self::C2::T%);
}
}
class E1<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1<core::int> a = #C5;
final field self::E1::T% b;
final field self::E1::T% c;
final field self::E1::T% d;
final field core::Type f;
static const field core::List<self::E1<dynamic>> values = #C6;
const constructor •(core::int #index, core::String #name, self::E1::T% a, self::E1::T% b) → self::E1<self::E1::T%>
: self::E1::b = b, self::E1::c = a, self::E1::d = b, self::E1::f = self::E1::T%, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2<T extends core::Object? = dynamic> extends core::_Enum /*isEnum*/ {
final field self::E2::T% b;
enum-element static const field self::E2<core::int> a = #C7;
final field self::E2::T% d;
final field self::E2::T% e;
final field core::Type f;
static const field core::List<self::E2<dynamic>> values = #C8;
const constructor •(core::int #index, core::String #name, self::E2::T% a, final self::E2::T% b) → self::E2<self::E2::T%>
: self::E2::d = a, self::E2::e = b, self::E2::f = self::E2::T%, self::E2::b = b, super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor other = self::ET1|constructor#other;
constructor tearoff other = self::ET1|constructor#_#other#tearOff;
}
extension type ET2<T extends core::Object? = dynamic>(T% a) {
abstract extension-type-member representation-field get a() → T%;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#<T extends core::Object? = dynamic>(self::ET1|constructor#::T% a) → self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#::T%>% /* erasure=self::ET1|constructor#::T%, declared=! */ #this = a;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#new#tearOff::T% a) → self::ET1<self::ET1|constructor#_#new#tearOff::T%>% /* erasure=self::ET1|constructor#_#new#tearOff::T%, declared=! */
return self::ET1|constructor#<self::ET1|constructor#_#new#tearOff::T%>(a);
static extension-type-member method ET1|constructor#other<T extends core::Object? = dynamic>(self::ET1|constructor#other::T% a) → self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ {
lowered final self::ET1<self::ET1|constructor#other::T%>% /* erasure=self::ET1|constructor#other::T%, declared=! */ #this = a;
{
core::print(self::ET1|constructor#other::T%);
}
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#other#tearOff<T extends core::Object? = dynamic>(self::ET1|constructor#_#other#tearOff::T% a) → self::ET1<self::ET1|constructor#_#other#tearOff::T%>% /* erasure=self::ET1|constructor#_#other#tearOff::T%, declared=! */
return self::ET1|constructor#other<self::ET1|constructor#_#other#tearOff::T%>(a);
static extension-type-member method ET2|constructor#<T extends core::Object? = dynamic>(self::ET2|constructor#::T% a) → self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ {
lowered final self::ET2<self::ET2|constructor#::T%>% /* erasure=self::ET2|constructor#::T%, declared=! */ #this = a;
{
core::print(self::ET2|constructor#::T%);
}
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff<T extends core::Object? = dynamic>(self::ET2|constructor#_#new#tearOff::T% a) → self::ET2<self::ET2|constructor#_#new#tearOff::T%>% /* erasure=self::ET2|constructor#_#new#tearOff::T%, declared=! */
return self::ET2|constructor#<self::ET2|constructor#_#new#tearOff::T%>(a);
constants {
#C1 = 1
#C2 = 0
#C3 = TypeLiteralConstant(core::int)
#C4 = "a"
#C5 = self::E1<core::int> {b:#C1, c:#C2, d:#C1, f:#C3, index:#C2, _name:#C4}
#C6 = <self::E1<dynamic>>[#C5]
#C7 = self::E2<core::int> {b:#C1, d:#C2, e:#C1, f:#C3, index:#C2, _name:#C4}
#C8 = <self::E2<dynamic>>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///generic_primary_constructor.dart:
- E1. (from org-dartlang-testcase:///generic_primary_constructor.dart:37:9)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///generic_primary_constructor.dart:40:11)
@@ -0,0 +1,29 @@
class C1<T> {
T b;
final T c;
T d;
T e;
T f;
Type g = T;
C1(T a, this.b, this.c) : d = a, e = b, f = c, g = T {}
}
class C2<T>(T a, var T b, final T c) {
T d = a;
T e = b;
T f = c;
Type g = T;
this {}
}
enum E1<T> { a<int>(0, 1); final T b; final T c; final T d; final Type f; const E1(T a, this.b) : c = a, d = b, f = T; }
enum E2<T>(T a, final T b) { a<int>(0, 1); final T d = a; final T e = b; final Type f = T; }
extension type ET1<T>(T a) {
ET1.other(this.a) {}
}
extension type ET2<T>(T a) {
this {}
}
@@ -0,0 +1,29 @@
class C1<T> {
C1(T a, this.b, this.c) : d = a, e = b, f = c, g = T {}
T b;
T d;
T e;
T f;
Type g = T;
final T c;
}
class C2<T>(T a, var T b, final T c) {
T d = a;
T e = b;
T f = c;
Type g = T;
this {}
}
enum E1<T> { a<int>(0, 1); final T b; final T c; final T d; final Type f; const E1(T a, this.b) : c = a, d = b, f = T; }
enum E2<T>(T a, final T b) { a<int>(0, 1); final T d = a; final T e = b; final Type f = T; }
extension type ET1<T>(T a) {
ET1.other(this.a) {}
}
extension type ET2<T>(T a) {
this {}
}
@@ -0,0 +1,29 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
class C1([@m int x = m]) {
static const int m = 42;
}
class C2(int x) { // Error
static const String int = 'not a type';
}
enum E1([@a int x = m]) {
a(0);
static const int m = 42;
}
enum E2(int x) { // Error
a(0);
static const String int = 'not a type';
}
extension type ET1([@m int x = m]) {
static const int m = 42;
}
extension type ET2(int x) { // Error
static const String int = 'not a type';
}
@@ -0,0 +1,96 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:9:10: Error: 'int' isn't a type.
// class C2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:18:9: Error: 'int' isn't a type.
// enum E2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:27:20: Error: 'int' isn't a type.
// extension type ET2(int x) { // Error
// ^^^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
static const field core::int m = #C1;
constructor •([@#C1 core::int x = #C1]) → self::C1
: super core::Object::•()
;
}
class C2 extends core::Object {
static const field core::String int = #C2;
constructor •(core::int x) → self::C2
: super core::Object::•()
;
}
class E1 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1 a = #C5;
static const field core::int m = #C1;
static const field core::List<self::E1> values = #C6;
const constructor •(core::int #index, core::String #name, [@#C5 core::int x = #C1]) → self::E1
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E2 a = #C7;
static const field core::String int = #C2;
static const field core::List<self::E2> values = #C8;
const constructor •(core::int #index, core::String #name, core::int x) → self::E2
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field m = self::ET1|m;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::int ET1|m = #C1;
static const field core::String ET2|int = #C2;
static extension-type-member method ET1|constructor#([@#C1 core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff([core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(x);
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = 42
#C2 = "not a type"
#C3 = 0
#C4 = "a"
#C5 = self::E1 {index:#C3, _name:#C4}
#C6 = <self::E1>[#C5]
#C7 = self::E2 {index:#C3, _name:#C4}
#C8 = <self::E2>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///parameter_scope.dart:
- E1. (from org-dartlang-testcase:///parameter_scope.dart:13:8)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///parameter_scope.dart:18:8)
@@ -0,0 +1,96 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:9:10: Error: 'int' isn't a type.
// class C2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:18:9: Error: 'int' isn't a type.
// enum E2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:27:20: Error: 'int' isn't a type.
// extension type ET2(int x) { // Error
// ^^^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
static const field core::int m = #C1;
constructor •([@#C1 core::int x = #C1]) → self::C1
: super core::Object::•()
;
}
class C2 extends core::Object {
static const field core::String int = #C2;
constructor •(core::int x) → self::C2
: super core::Object::•()
;
}
class E1 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1 a = #C5;
static const field core::int m = #C1;
static const field core::List<self::E1> values = #C6;
const constructor •(core::int #index, core::String #name, [@#C5 core::int x = #C1]) → self::E1
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E2 a = #C7;
static const field core::String int = #C2;
static const field core::List<self::E2> values = #C8;
const constructor •(core::int #index, core::String #name, core::int x) → self::E2
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field m = self::ET1|m;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::int ET1|m = #C1;
static const field core::String ET2|int = #C2;
static extension-type-member method ET1|constructor#([@#C1 core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff([core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(x);
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = 42
#C2 = "not a type"
#C3 = 0
#C4 = "a"
#C5 = self::E1 {index:#C3, _name:#C4}
#C6 = <self::E1>[#C5]
#C7 = self::E2 {index:#C3, _name:#C4}
#C8 = <self::E2>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///parameter_scope.dart:
- E1. (from org-dartlang-testcase:///parameter_scope.dart:13:8)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///parameter_scope.dart:18:8)
@@ -0,0 +1,67 @@
library;
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
static const field core::int m = 42;
constructor •([core::int x = self::C1::m]) → self::C1
;
}
class C2 extends core::Object {
static const field core::String int = "not a type";
constructor •(core::int x) → self::C2
;
}
class E1 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1 a = const self::E1::•(0, "a", 0);
static const field core::int m = 42;
static const field core::List<self::E1> values = const <self::E1>[self::E1::a];
const constructor •(core::int #index, core::String #name, [core::int x = self::E1::m]) → self::E1
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E2 a = const self::E2::•(0, "a", 0);
static const field core::String int = "not a type";
static const field core::List<self::E2> values = const <self::E2>[self::E2::a];
const constructor •(core::int #index, core::String #name, core::int x) → self::E2
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field m = self::ET1|m;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::int ET1|m = 42;
static const field core::String ET2|int = "not a type";
static extension-type-member method ET1|constructor#([core::int x = self::ET1|m]) → self::ET1% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#new#tearOff([has-declared-initializer core::int x]) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(x);
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
Extra constant evaluation status:
Evaluated: StaticGet @ org-dartlang-testcase:///parameter_scope.dart:5:22 -> IntConstant(42)
Evaluated: StaticGet @ org-dartlang-testcase:///parameter_scope.dart:13:21 -> IntConstant(42)
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///parameter_scope.dart:14:3 -> InstanceConstant(const E1{_Enum.index: 0, _Enum._name: "a"})
Evaluated: ListLiteral @ org-dartlang-testcase:///parameter_scope.dart:13:6 -> ListConstant(const <E1>[const E1{_Enum.index: 0, _Enum._name: "a"}])
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///parameter_scope.dart:19:3 -> InstanceConstant(const E2{_Enum.index: 0, _Enum._name: "a"})
Evaluated: ListLiteral @ org-dartlang-testcase:///parameter_scope.dart:18:6 -> ListConstant(const <E2>[const E2{_Enum.index: 0, _Enum._name: "a"}])
Evaluated: StaticGet @ org-dartlang-testcase:///parameter_scope.dart:23:32 -> IntConstant(42)
Extra constant evaluation: evaluated: 21, effectively constant: 7
@@ -0,0 +1,96 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:9:10: Error: 'int' isn't a type.
// class C2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:18:9: Error: 'int' isn't a type.
// enum E2(int x) { // Error
// ^^^
//
// pkg/front_end/testcases/primary_constructors/parameter_scope.dart:27:20: Error: 'int' isn't a type.
// extension type ET2(int x) { // Error
// ^^^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
static const field core::int m = #C1;
constructor •([@#C1 core::int x = #C1]) → self::C1
: super core::Object::•()
;
}
class C2 extends core::Object {
static const field core::String int = #C2;
constructor •(core::int x) → self::C2
: super core::Object::•()
;
}
class E1 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E1 a = #C5;
static const field core::int m = #C1;
static const field core::List<self::E1> values = #C6;
const constructor •(core::int #index, core::String #name, [@#C5 core::int x = #C1]) → self::E1
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E1.${this.{core::_Enum::_name}{core::String}}";
}
class E2 extends core::_Enum /*isEnum*/ {
enum-element static const field self::E2 a = #C7;
static const field core::String int = #C2;
static const field core::List<self::E2> values = #C8;
const constructor •(core::int #index, core::String #name, core::int x) → self::E2
: super core::_Enum::•(#index, #name)
;
method core::_enumToString() → core::String
return "E2.${this.{core::_Enum::_name}{core::String}}";
}
extension type ET1(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field m = self::ET1|m;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::int ET1|m = #C1;
static const field core::String ET2|int = #C2;
static extension-type-member method ET1|constructor#([@#C1 core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff([core::int x = #C1]) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(x);
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = 42
#C2 = "not a type"
#C3 = 0
#C4 = "a"
#C5 = self::E1 {index:#C3, _name:#C4}
#C6 = <self::E1>[#C5]
#C7 = self::E2 {index:#C3, _name:#C4}
#C8 = <self::E2>[#C7]
}
Constructor coverage from constants:
org-dartlang-testcase:///parameter_scope.dart:
- E1. (from org-dartlang-testcase:///parameter_scope.dart:13:8)
- _Enum. (from org-dartlang-sdk:///sdk/lib/core/enum.dart)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
- E2. (from org-dartlang-testcase:///parameter_scope.dart:18:8)
@@ -0,0 +1,19 @@
class C1([@m int x = m]) {
static const int m = 42;
}
class C2(int x) {
static const String int = 'not a type';
}
enum E1([@a int x = m]) { a(0); static const int m = 42; }
enum E2(int x) { a(0); static const String int = 'not a type'; }
extension type ET1([@m int x = m]) {
static const int m = 42;
}
extension type ET2(int x) {
static const String int = 'not a type';
}
@@ -0,0 +1,19 @@
class C1([@m int x = m]) {
static const int m = 42;
}
class C2(int x) {
static const String int = 'not a type';
}
enum E1([@a int x = m]) { a(0); static const int m = 42; }
enum E2(int x) { a(0); static const String int = 'not a type'; }
extension type ET1([@m int x = m]) {
static const int m = 42;
}
extension type ET2(int x) {
static const String int = 'not a type';
}
@@ -0,0 +1,9 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart=3.10
extension type ET2(int x) /* Ok */ {
static const String int = 'not a type';
}
@@ -0,0 +1,21 @@
library;
import self as self;
import "dart:core" as core;
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::String ET2|int = #C1;
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = "not a type"
}
@@ -0,0 +1,21 @@
library;
import self as self;
import "dart:core" as core;
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::String ET2|int = #C1;
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = "not a type"
}
@@ -0,0 +1,15 @@
library;
import self as self;
import "dart:core" as core;
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::String ET2|int = "not a type";
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
@@ -0,0 +1,21 @@
library;
import self as self;
import "dart:core" as core;
extension type ET2(core::int x) {
abstract extension-type-member representation-field get x() → core::int;
static field int = self::ET2|int;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static const field core::String ET2|int = #C1;
static extension-type-member method ET2|constructor#(core::int x) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = x;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int x) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(x);
constants {
#C1 = "not a type"
}
@@ -0,0 +1,5 @@
// @dart = 3.10
extension type ET2(int x) {
static const String int = 'not a type';
}
@@ -0,0 +1,5 @@
// @dart = 3.10
extension type ET2(int x) {
static const String int = 'not a type';
}
@@ -0,0 +1,33 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// Formal parameter types of primary constructor are resolved within the body
// scope of the enclosing declaration.
// SharedOptions=--enable-experiment=primary-constructors
class C(int x) {
// ^
// [analyzer] unspecified
// [cfe] 'int' isn't a type.
static const String int = 'not a type';
}
enum E(int x) {
// ^
// [cfe] 'int' isn't a type.
// [analyzer] unspecified
a(0);
static const String int = 'not a type';
}
extension type ET(int x) {
// ^
// [analyzer] unspecified
// [cfe] 'int' isn't a type.
static const String int = 'not a type';
}
@@ -0,0 +1,20 @@
// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
// @dart=3.10
// Prior to the primary-constructors feature, formal parameter types of
// primary constructor were not resolved within the body scope of the
// enclosing declaration.
// SharedOptions=--enable-experiment=primary-constructors
extension type ET(int x) {
static const String int = 'not a type';
}
main() {
print(ET(0));
print(ET.int);
}