[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>
This commit is contained in:
Johnni Winther
2026-03-10 02:55:53 -07:00
committed by Commit Queue
parent e68cb1deb7
commit a6bc2c3608
34 changed files with 1032 additions and 182 deletions
@@ -2566,6 +2566,16 @@ const MessageCode recordTypeZeroFieldsButTrailingComma = const MessageCode(
correctionMessage: """Try removing the trailing comma.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode
redirectGenerativeToNonGenerativeConstructor = const MessageCode(
"RedirectGenerativeToNonGenerativeConstructor",
sharedCode: SharedCode.redirectGenerativeToNonGenerativeConstructor,
problemMessage:
"""Generative constructors can't redirect to a factory constructor.""",
correctionMessage: """Try redirecting to a different constructor.""",
);
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const MessageCode redirectingConstructorWithBody = const MessageCode(
"RedirectingConstructorWithBody",
@@ -3187,6 +3197,7 @@ enum SharedCode {
primaryConstructorBodyWithoutDeclaration,
recordLiteralOnePositionalNoTrailingComma,
recordTypeOnePositionalNoTrailingComma,
redirectGenerativeToNonGenerativeConstructor,
redirectingConstructorWithBody,
redirectionInNonFactoryConstructor,
sealedEnum,
+52
View File
@@ -2706,3 +2706,55 @@ fieldInitializedInDeclarationAndParameterOfPrimaryConstructor:
class C(this.x) {
int x = 0;
}
redirectGenerativeToNonGenerativeConstructor:
type: compileTimeError
parameters: none
problemMessage: "Generative constructors can't redirect to a factory constructor."
correctionMessage: Try redirecting to a different constructor.
hasPublishedDocs: true
analyzerCode: redirectGenerativeToNonGenerativeConstructor
documentation: |-
#### Description
The analyzer produces this diagnostic when a generative constructor
redirects to a factory constructor.
#### Example
The following code produces this diagnostic because the generative
constructor `C.a` redirects to the factory constructor `C.b`:
```dart
class C {
C.a() : [!this.b()!];
factory C.b() => C.a();
}
```
#### Common fixes
If the generative constructor doesn't need to redirect to another
constructor, then remove the redirect.
```dart
class C {
C.a();
factory C.b() => C.a();
}
```
If the generative constructor must redirect to another constructor, then
make the other constructor be a generative (non-factory) constructor:
```dart
class C {
C.a() : this.b();
C.b();
}
```
script: |
class C {
factory C() => throw '';
C.named() : this();
}
@@ -1287,6 +1287,7 @@ final sharedAnalyzerCodes = <DiagnosticCode>[
diag.primaryConstructorBodyWithoutDeclaration,
diag.recordLiteralOnePositionalNoTrailingComma,
diag.recordTypeOnePositionalNoTrailingComma,
diag.redirectGenerativeToNonGenerativeConstructor,
diag.redirectingConstructorWithBody,
diag.redirectionInNonFactoryConstructor,
diag.sealedEnum,
-45
View File
@@ -15418,51 +15418,6 @@ CompileTimeErrorCode:
C.a();
}
```
redirectGenerativeToNonGenerativeConstructor:
type: compileTimeError
parameters: none
problemMessage: "Generative constructors can't redirect to a factory constructor."
correctionMessage: Try redirecting to a different constructor.
hasPublishedDocs: true
documentation: |-
#### Description
The analyzer produces this diagnostic when a generative constructor
redirects to a factory constructor.
#### Example
The following code produces this diagnostic because the generative
constructor `C.a` redirects to the factory constructor `C.b`:
```dart
class C {
C.a() : [!this.b()!];
factory C.b() => C.a();
}
```
#### Common fixes
If the generative constructor doesn't need to redirect to another
constructor, then remove the redirect.
```dart
class C {
C.a();
factory C.b() => C.a();
}
```
If the generative constructor must redirect to another constructor, then
make the other constructor be a generative (non-factory) constructor:
```dart
class C {
C.a() : this.b();
C.b();
}
```
redirectToAbstractClassConstructor:
type: compileTimeError
parameters:
+61 -23
View File
@@ -35,7 +35,6 @@ import 'package:_fe_analyzer_shared/src/scanner/token_impl.dart'
import 'package:_fe_analyzer_shared/src/type_inference/assigned_variables.dart';
import 'package:_fe_analyzer_shared/src/util/link.dart';
import 'package:_fe_analyzer_shared/src/util/value_kind.dart';
import 'package:front_end/src/codes/diagnostic.dart' as diag;
import 'package:kernel/ast.dart';
import 'package:kernel/class_hierarchy.dart';
import 'package:kernel/core_types.dart';
@@ -86,8 +85,11 @@ import '../builder/type_builder.dart';
import '../builder/variable_builder.dart';
import '../builder/void_type_builder.dart';
import '../codes/cfe_codes.dart' as cfe;
import '../codes/diagnostic.dart' as diag;
import '../source/check_helper.dart';
import '../source/diet_parser.dart';
import '../source/source_constructor_builder.dart';
import '../source/source_factory_builder.dart';
import '../source/source_library_builder.dart';
import '../source/source_member_builder.dart';
import '../source/source_property_builder.dart';
@@ -10088,8 +10090,8 @@ class BodyBuilderImpl extends StackListenerImpl
ActualArguments arguments, {
required int fileOffset,
}) {
Builder? constructorBuilder = _context.lookupConstructor(name);
if (constructorBuilder == null) {
MemberLookupResult? result = _context.lookupConstructor(name);
if (result == null) {
int length = name.text.length;
if (length == 0) {
// The constructor is unnamed so the offset points to 'this'.
@@ -10105,30 +10107,66 @@ class BodyBuilderImpl extends StackListenerImpl
),
isRedirectingInitializer: true,
);
} else if (result.isInvalidLookup) {
return createInvalidInitializer(
LookupResult.createDuplicateExpression(
result,
context: compilerContext,
name: name.text,
fileUri: uri,
fileOffset: fileOffset,
length: noLength,
),
isRedirectingInitializer: true,
);
} else {
if (_context.isConstructorCyclic(name.text)) {
int length = name.text.length;
if (length == 0) length = "this".length;
addProblem(diag.constructorCyclic, fileOffset, length);
// TODO(askesc): Produce invalid initializer.
}
if (_context.formals != null) {
for (FormalParameterBuilder formal in _context.formals!) {
if (formal.isSuperInitializingFormal) {
addProblem(
diag.unexpectedSuperParametersInGenerativeConstructors,
formal.fileOffset,
noLength,
);
_context.markAsErroneous();
MemberBuilder builder = result.getable!;
if (builder is SourceFactoryBuilder) {
return createInvalidInitializer(
buildProblem(
message: diag.redirectGenerativeToNonGenerativeConstructor,
fileUri: uri,
fileOffset: fileOffset,
length: noLength,
),
isRedirectingInitializer: true,
);
} else {
assert(
builder is SourceConstructorBuilder,
"Unexpected constructor builder $builder.",
);
if (_context.isConstructorCyclic(name.text)) {
int length = name.text.length;
if (length == 0) length = "this".length;
return createInvalidInitializer(
buildProblem(
message: diag.constructorCyclic,
fileUri: uri,
fileOffset: fileOffset,
length: length,
),
isRedirectingInitializer: true,
);
}
if (_context.formals != null) {
for (FormalParameterBuilder formal in _context.formals!) {
if (formal.isSuperInitializingFormal) {
addProblem(
diag.unexpectedSuperParametersInGenerativeConstructors,
formal.fileOffset,
noLength,
);
_context.markAsErroneous();
}
}
}
return _context.buildRedirectingInitializer(
builder,
arguments,
fileOffset: fileOffset,
);
}
return _context.buildRedirectingInitializer(
constructorBuilder,
arguments,
fileOffset: fileOffset,
);
}
}
@@ -10,15 +10,14 @@ import 'package:kernel/transformations/flags.dart';
import '../base/constant_context.dart' show ConstantContext;
import '../base/local_scope.dart';
import '../base/lookup_result.dart';
import '../builder/builder.dart';
import '../builder/declaration_builders.dart';
import '../builder/formal_parameter_builder.dart';
import '../builder/library_builder.dart';
import '../builder/member_builder.dart';
import '../builder/named_type_builder.dart';
import '../builder/type_builder.dart';
import '../dill/dill_class_builder.dart';
import '../source/source_class_builder.dart';
import '../source/source_constructor_builder.dart';
import '../source/source_enum_builder.dart';
import '../source/source_extension_builder.dart';
import '../source/source_extension_type_declaration_builder.dart';
@@ -94,7 +93,7 @@ abstract class BodyBuilderContext {
}
/// Looks up the constructor by the given [name] in the enclosing declaration.
Builder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
return declarationContext.lookupConstructor(name);
}
@@ -102,7 +101,7 @@ abstract class BodyBuilderContext {
/// [constructorBuilder] with the given [arguments] from within a constructor
/// in the same class.
Initializer buildRedirectingInitializer(
Builder constructorBuilder,
MemberBuilder constructorBuilder,
ActualArguments arguments, {
required int fileOffset,
}) {
@@ -459,12 +458,12 @@ abstract class BodyBuilderDeclarationContext {
throw new UnsupportedError('${runtimeType}.lookupSuperMember');
}
Builder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
throw new UnsupportedError('${runtimeType}.lookupConstructor');
}
Initializer buildRedirectingInitializer(
Builder constructorBuilder,
MemberBuilder constructorBuilder,
ActualArguments arguments, {
required int fileOffset,
}) {
@@ -568,13 +567,13 @@ class _SourceClassBodyBuilderDeclarationContext
}
@override
SourceConstructorBuilder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
return _sourceClassBuilder.lookupConstructor(name);
}
@override
Initializer buildRedirectingInitializer(
covariant SourceConstructorBuilder constructorBuilder,
MemberBuilder constructorBuilder,
ActualArguments arguments, {
required int fileOffset,
}) {
@@ -667,7 +666,7 @@ class _SourceExtensionTypeDeclarationBodyBuilderDeclarationContext
_sourceExtensionTypeDeclarationBuilder;
@override
SourceConstructorBuilder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
return _sourceExtensionTypeDeclarationBuilder.lookupConstructor(name);
}
@@ -679,7 +678,7 @@ class _SourceExtensionTypeDeclarationBodyBuilderDeclarationContext
@override
Initializer buildRedirectingInitializer(
covariant SourceConstructorBuilder constructorBuilder,
MemberBuilder constructorBuilder,
ActualArguments arguments, {
required int fileOffset,
}) {
@@ -6664,7 +6664,7 @@ class ThisAccessGenerator extends Generator {
return createInvalidInitializer(
LookupResult.createDuplicateExpression(
result,
context: _helper.libraryBuilder.loader.target.context,
context: _helper.compilerContext,
name: name.text,
fileUri: _helper.uri,
fileOffset: offset,
@@ -642,16 +642,12 @@ class SourceClassBuilder extends ClassBuilderImpl
/// Looks up the constructor by [name] on the class built by this class
/// builder.
SourceConstructorBuilder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
if (name.text == "new") {
name = new Name("", name.library);
}
Builder? builder = nameSpace.lookupConstructor(name.text)?.getable;
if (builder is SourceConstructorBuilder) {
return builder;
}
return null;
return nameSpace.lookupConstructor(name.text);
}
/// Looks up the super constructor by [name] on the superclass of the class
@@ -10,13 +10,13 @@ import 'package:kernel/reference_from_index.dart';
import 'package:kernel/type_algebra.dart';
import 'package:kernel/type_environment.dart';
import '../base/lookup_result.dart';
import '../base/messages.dart';
import '../base/modifiers.dart';
import '../base/name_space.dart';
import '../base/problems.dart';
import '../base/scope.dart';
import '../builder/augmentation_iterator.dart';
import '../builder/builder.dart';
import '../builder/constructor_reference_builder.dart';
import '../builder/declaration_builders.dart';
import '../builder/formal_parameter_builder.dart';
@@ -34,7 +34,6 @@ import '../type_inference/type_inference_engine.dart';
import 'name_scheme.dart';
import 'name_space_builder.dart';
import 'source_builder_mixins.dart';
import 'source_constructor_builder.dart';
import 'source_factory_builder.dart';
import 'source_library_builder.dart';
import 'source_member_builder.dart';
@@ -1016,17 +1015,13 @@ class SourceExtensionTypeDeclarationBuilder
/// Looks up the constructor by [name] on the class built by this class
/// builder.
SourceConstructorBuilder? lookupConstructor(Name name) {
MemberLookupResult? lookupConstructor(Name name) {
if (name.text == "new") {
// Coverage-ignore-block(suite): Not run.
name = new Name("", name.library);
}
Builder? builder = nameSpace.lookupConstructor(name.text)?.getable;
if (builder is SourceConstructorBuilder) {
return builder;
}
return null;
return nameSpace.lookupConstructor(name.text);
}
DartType get _declaredRepresentationType =>
@@ -20,13 +20,19 @@ class A extends core::Object {
: this self::A::bar()
;
constructor bar() → self::A
: this self::A::foo()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:7:18: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A.bar() : this.foo();
^^^"
;
constructor baz() → self::A
: this self::A::foo()
;
constructor •() → self::A
: this self::A::•()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:9:9: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A() : this();
^^^^"
;
}
static method main() → dynamic {}
@@ -20,13 +20,19 @@ class A extends core::Object {
: this self::A::bar()
;
constructor bar() → self::A
: this self::A::foo()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:7:18: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A.bar() : this.foo();
^^^"
;
constructor baz() → self::A
: this self::A::foo()
;
constructor •() → self::A
: this self::A::•()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:9:9: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A() : this();
^^^^"
;
}
static method main() → dynamic {}
@@ -20,13 +20,19 @@ class A extends core::Object {
: this self::A::bar()
;
constructor bar() → self::A
: this self::A::foo()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:7:18: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A.bar() : this.foo();
^^^"
;
constructor baz() → self::A
: this self::A::foo()
;
constructor •() → self::A
: this self::A::•()
: invalid-initializer "pkg/front_end/testcases/general/constructor_cycle.dart:9:9: Error: Redirecting constructors can't be cyclic.
Try to have all constructors eventually redirect to a non-redirecting constructor.
A() : this();
^^^^"
;
}
static method main() → dynamic {}
@@ -76,35 +76,19 @@ library;
// C<T>() : this();
// ^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
// C<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
// C!<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:4:11: Error: Couldn't find constructor 'C'.
// C<T() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:5:13: Error: Couldn't find constructor 'C'.
// C<T>=() : this();
// ^^^^
//
import self as self;
import "dart:core" as core;
class C extends core::Object {
field dynamic C = null;
constructor •() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Can't use 'new' because it is declared more than once.
C<T>() : this();
^^^^"
^"
;
constructor !() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Can't use 'new' because it is declared more than once.
C!<T>() : this();
^^^^"
^"
;
}
@@ -76,35 +76,19 @@ library;
// C<T>() : this();
// ^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
// C<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
// C!<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:4:11: Error: Couldn't find constructor 'C'.
// C<T() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:5:13: Error: Couldn't find constructor 'C'.
// C<T>=() : this();
// ^^^^
//
import self as self;
import "dart:core" as core;
class C extends core::Object {
field dynamic C = null;
constructor •() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Can't use 'new' because it is declared more than once.
C<T>() : this();
^^^^"
^"
;
constructor !() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Can't use 'new' because it is declared more than once.
C!<T>() : this();
^^^^"
^"
;
}
@@ -76,35 +76,19 @@ library;
// C<T>() : this();
// ^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
// C<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
// C!<T>() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:4:11: Error: Couldn't find constructor 'C'.
// C<T() : this();
// ^^^^
//
// pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:5:13: Error: Couldn't find constructor 'C'.
// C<T>=() : this();
// ^^^^
//
import self as self;
import "dart:core" as core;
class C extends core::Object {
field dynamic C = null;
constructor •() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:2:12: Error: Can't use 'new' because it is declared more than once.
C<T>() : this();
^^^^"
^"
;
constructor !() → self::C
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Couldn't find constructor 'C'.
: invalid-initializer "pkg/front_end/testcases/general/error_recovery/constructor_recovery_type_parameters.dart:3:13: Error: Can't use 'new' because it is declared more than once.
C!<T>() : this();
^^^^"
^"
;
}
@@ -0,0 +1,25 @@
// 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 {
C1();
C1();
C1.named() : this();
}
class C2 {
C2.named();
C2.named();
C2() : this.named();
}
extension type ET1(int i) {
ET1(this.i);
ET1.named(int i) : this(i);
}
extension type ET2.named(int i) {
ET2.named(this.i);
ET2(int i) : this.named(i);
}
@@ -0,0 +1,99 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:7:3: Error: 'C1' is already declared in this scope.
// C1();
// ^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:6:3: Context: Previous declaration of 'C1'.
// C1();
// ^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:13:3: Error: 'C2.named' is already declared in this scope.
// C2.named();
// ^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:12:3: Context: Previous declaration of 'C2.named'.
// C2.named();
// ^^^^^^^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:18:3: Error: 'ET1' is already declared in this scope.
// ET1(this.i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:17:19: Context: Previous declaration of 'ET1'.
// extension type ET1(int i) {
// ^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:23:3: Error: 'ET2.named' is already declared in this scope.
// ET2.named(this.i);
// ^^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:22:20: Context: Previous declaration of 'ET2.named'.
// extension type ET2.named(int i) {
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor •() → self::C1
: super core::Object::•()
;
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:8:16: Error: Can't use 'new' because it is declared more than once.
C1.named() : this();
^"
;
}
class C2 extends core::Object {
constructor named() → self::C2
: super core::Object::•()
;
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:14:15: Error: Can't use 'named' because it is declared more than once.
C2() : this.named();
^"
;
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET2|constructor#named;
constructor tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:19:22: Error: Can't use 'new' because it is declared more than once.
ET1.named(int i) : this(i);
^";
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:24:21: Error: Can't use 'named' because it is declared more than once.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,99 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:7:3: Error: 'C1' is already declared in this scope.
// C1();
// ^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:6:3: Context: Previous declaration of 'C1'.
// C1();
// ^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:13:3: Error: 'C2.named' is already declared in this scope.
// C2.named();
// ^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:12:3: Context: Previous declaration of 'C2.named'.
// C2.named();
// ^^^^^^^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:18:3: Error: 'ET1' is already declared in this scope.
// ET1(this.i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:17:19: Context: Previous declaration of 'ET1'.
// extension type ET1(int i) {
// ^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:23:3: Error: 'ET2.named' is already declared in this scope.
// ET2.named(this.i);
// ^^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:22:20: Context: Previous declaration of 'ET2.named'.
// extension type ET2.named(int i) {
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor •() → self::C1
: super core::Object::•()
;
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:8:16: Error: Can't use 'new' because it is declared more than once.
C1.named() : this();
^"
;
}
class C2 extends core::Object {
constructor named() → self::C2
: super core::Object::•()
;
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:14:15: Error: Can't use 'named' because it is declared more than once.
C2() : this.named();
^"
;
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET2|constructor#named;
constructor tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:19:22: Error: Can't use 'new' because it is declared more than once.
ET1.named(int i) : this(i);
^";
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:24:21: Error: Can't use 'named' because it is declared more than once.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,77 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:7:3: Error: 'C1' is already declared in this scope.
// C1();
// ^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:6:3: Context: Previous declaration of 'C1'.
// C1();
// ^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:13:3: Error: 'C2.named' is already declared in this scope.
// C2.named();
// ^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:12:3: Context: Previous declaration of 'C2.named'.
// C2.named();
// ^^^^^^^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:18:3: Error: 'ET1' is already declared in this scope.
// ET1(this.i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:17:19: Context: Previous declaration of 'ET1'.
// extension type ET1(int i) {
// ^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:23:3: Error: 'ET2.named' is already declared in this scope.
// ET2.named(this.i);
// ^^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:22:20: Context: Previous declaration of 'ET2.named'.
// extension type ET2.named(int i) {
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor •() → self::C1
;
constructor named() → self::C1
;
}
class C2 extends core::Object {
constructor named() → self::C2
;
constructor •() → self::C2
;
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET2|constructor#named;
constructor tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,99 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:7:3: Error: 'C1' is already declared in this scope.
// C1();
// ^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:6:3: Context: Previous declaration of 'C1'.
// C1();
// ^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:13:3: Error: 'C2.named' is already declared in this scope.
// C2.named();
// ^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:12:3: Context: Previous declaration of 'C2.named'.
// C2.named();
// ^^^^^^^^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:18:3: Error: 'ET1' is already declared in this scope.
// ET1(this.i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:17:19: Context: Previous declaration of 'ET1'.
// extension type ET1(int i) {
// ^
//
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:23:3: Error: 'ET2.named' is already declared in this scope.
// ET2.named(this.i);
// ^^^^^^^^^
// pkg/front_end/testcases/general/redirect_to_duplicate.dart:22:20: Context: Previous declaration of 'ET2.named'.
// extension type ET2.named(int i) {
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor •() → self::C1
: super core::Object::•()
;
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:8:16: Error: Can't use 'new' because it is declared more than once.
C1.named() : this();
^"
;
}
class C2 extends core::Object {
constructor named() → self::C2
: super core::Object::•()
;
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_duplicate.dart:14:15: Error: Can't use 'named' because it is declared more than once.
C2() : this.named();
^"
;
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor • = self::ET1|constructor#;
constructor tearoff • = self::ET1|constructor#_#new#tearOff;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET2|constructor#named;
constructor tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:19:22: Error: Can't use 'new' because it is declared more than once.
ET1.named(int i) : this(i);
^";
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_duplicate.dart:24:21: Error: Can't use 'named' because it is declared more than once.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,21 @@
class C1 {
C1();
C1();
C1.named() : this();
}
class C2 {
C2.named();
C2.named();
C2() : this.named();
}
extension type ET1(int i) {
ET1(this.i);
ET1.named(int i) : this(i);
}
extension type ET2.named(int i) {
ET2.named(this.i);
ET2(int i) : this.named(i);
}
@@ -0,0 +1,21 @@
class C1 {
C1();
C1();
C1.named() : this();
}
class C2 {
C2() : this.named();
C2.named();
C2.named();
}
extension type ET1(int i) {
ET1(this.i);
ET1.named(int i) : this(i);
}
extension type ET2.named(int i) {
ET2(int i) : this.named(i);
ET2.named(this.i);
}
@@ -0,0 +1,23 @@
// 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 {
factory C1() => throw '';
C1.named() : this();
}
class C2 {
factory C2.named() => throw '';
C2() : this.named();
}
extension type ET1.named(int i) {
factory ET1(int i) => throw '';
ET1(int i) : this(i);
}
extension type ET2.other(int i) {
factory ET2.named(int i) => throw '';
ET2(int i) : this.named(i);
}
@@ -0,0 +1,95 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:17:3: Error: 'ET1' is already declared in this scope.
// ET1(int i) : this(i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_factory.dart:16:11: Context: Previous declaration of 'ET1'.
// factory ET1(int i) => throw '';
// ^^^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C1.named() : this();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C2() : this.named();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// ET2(int i) : this.named(i);
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C1.named() : this();
^"
;
static factory •() → self::C1
return throw "";
}
class C2 extends core::Object {
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C2() : this.named();
^"
;
static factory named() → self::C2
return throw "";
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
static factory • = self::ET1|constructor#;
static factory tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor other = self::ET2|constructor#other;
constructor tearoff other = self::ET2|constructor#_#other#tearOff;
static factory named = self::ET2|constructor#named;
static factory tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET2|constructor#other(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#other#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#other(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,95 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:17:3: Error: 'ET1' is already declared in this scope.
// ET1(int i) : this(i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_factory.dart:16:11: Context: Previous declaration of 'ET1'.
// factory ET1(int i) => throw '';
// ^^^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C1.named() : this();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C2() : this.named();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// ET2(int i) : this.named(i);
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C1.named() : this();
^"
;
static factory •() → self::C1
return throw "";
}
class C2 extends core::Object {
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C2() : this.named();
^"
;
static factory named() → self::C2
return throw "";
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
static factory • = self::ET1|constructor#;
static factory tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor other = self::ET2|constructor#other;
constructor tearoff other = self::ET2|constructor#_#other#tearOff;
static factory named = self::ET2|constructor#named;
static factory tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET2|constructor#other(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#other#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#other(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,62 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:17:3: Error: 'ET1' is already declared in this scope.
// ET1(int i) : this(i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_factory.dart:16:11: Context: Previous declaration of 'ET1'.
// factory ET1(int i) => throw '';
// ^^^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor named() → self::C1
;
static factory •() → self::C1
;
}
class C2 extends core::Object {
constructor •() → self::C2
;
static factory named() → self::C2
;
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
static factory • = self::ET1|constructor#;
static factory tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor other = self::ET2|constructor#other;
constructor tearoff other = self::ET2|constructor#_#other#tearOff;
static factory named = self::ET2|constructor#named;
static factory tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET2|constructor#other(core::int i) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#other#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#other(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */
;
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,95 @@
library;
//
// Problems in library:
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:17:3: Error: 'ET1' is already declared in this scope.
// ET1(int i) : this(i);
// ^^^
// pkg/front_end/testcases/general/redirect_to_factory.dart:16:11: Context: Previous declaration of 'ET1'.
// factory ET1(int i) => throw '';
// ^^^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C1.named() : this();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// C2() : this.named();
// ^
//
// pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
// Try redirecting to a different constructor.
// ET2(int i) : this.named(i);
// ^
//
import self as self;
import "dart:core" as core;
class C1 extends core::Object {
constructor named() → self::C1
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:7:16: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C1.named() : this();
^"
;
static factory •() → self::C1
return throw "";
}
class C2 extends core::Object {
constructor •() → self::C2
: invalid-initializer "pkg/front_end/testcases/general/redirect_to_factory.dart:12:15: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
C2() : this.named();
^"
;
static factory named() → self::C2
return throw "";
}
extension type ET1(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor named = self::ET1|constructor#named;
constructor tearoff named = self::ET1|constructor#_#named#tearOff;
static factory • = self::ET1|constructor#;
static factory tearoff • = self::ET1|constructor#_#new#tearOff;
}
extension type ET2(core::int i) {
abstract extension-type-member representation-field get i() → core::int;
constructor other = self::ET2|constructor#other;
constructor tearoff other = self::ET2|constructor#_#other#tearOff;
static factory named = self::ET2|constructor#named;
static factory tearoff named = self::ET2|constructor#_#named#tearOff;
constructor • = self::ET2|constructor#;
constructor tearoff • = self::ET2|constructor#_#new#tearOff;
}
static extension-type-member method ET1|constructor#named(core::int i) → self::ET1% /* erasure=core::int, declared=! */ {
lowered final self::ET1% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET1|constructor#_#named#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#named(i);
static extension-type-member method ET1|constructor#(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET1|constructor#_#new#tearOff(core::int i) → self::ET1% /* erasure=core::int, declared=! */
return self::ET1|constructor#(i);
static extension-type-member method ET2|constructor#other(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this = i;
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#other#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#other(i);
static extension-type-member method ET2|constructor#named(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return throw "";
static extension-type-member synthetic method ET2|constructor#_#named#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#named(i);
static extension-type-member method ET2|constructor#(core::int i) → self::ET2% /* erasure=core::int, declared=! */ {
lowered final self::ET2% /* erasure=core::int, declared=! */ #this;
invalid-expression "pkg/front_end/testcases/general/redirect_to_factory.dart:22:21: Error: Generative constructors can't redirect to a factory constructor.
Try redirecting to a different constructor.
ET2(int i) : this.named(i);
^";
return #this;
}
static extension-type-member synthetic method ET2|constructor#_#new#tearOff(core::int i) → self::ET2% /* erasure=core::int, declared=! */
return self::ET2|constructor#(i);
@@ -0,0 +1,19 @@
class C1 {
factory C1() => throw '';
C1.named() : this();
}
class C2 {
factory C2.named() => throw '';
C2() : this.named();
}
extension type ET1.named(int i) {
factory ET1(int i) => throw '';
ET1(int i) : this(i);
}
extension type ET2.other(int i) {
factory ET2.named(int i) => throw '';
ET2(int i) : this.named(i);
}
@@ -0,0 +1,19 @@
class C1 {
C1.named() : this();
factory C1() => throw '';
}
class C2 {
C2() : this.named();
factory C2.named() => throw '';
}
extension type ET1.named(int i) {
ET1(int i) : this(i);
factory ET1(int i) => throw '';
}
extension type ET2.other(int i) {
ET2(int i) : this.named(i);
factory ET2.named(int i) => throw '';
}
@@ -9,10 +9,6 @@ library;
// class C5(var int v) {
// ^
//
// pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
// C5.foo(int v) : this(v);
// ^^^^
//
import self as self;
import "dart:core" as core;
@@ -22,8 +18,8 @@ class C5 extends core::Object {
: self::C5::v = v, super core::Object::•()
;
constructor foo(core::int v) → self::C5
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Can't use 'new' because it is declared more than once.
C5.foo(int v) : this(v);
^^^^"
^"
;
}
@@ -9,10 +9,6 @@ library;
// class C5(var int v) {
// ^
//
// pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
// C5.foo(int v) : this(v);
// ^^^^
//
import self as self;
import "dart:core" as core;
@@ -22,8 +18,8 @@ class C5 extends core::Object {
: self::C5::v = v, super core::Object::•()
;
constructor foo(core::int v) → self::C5
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Can't use 'new' because it is declared more than once.
C5.foo(int v) : this(v);
^^^^"
^"
;
}
@@ -9,10 +9,6 @@ library;
// class C5(var int v) {
// ^
//
// pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
// C5.foo(int v) : this(v);
// ^^^^
//
import self as self;
import "dart:core" as core;
@@ -22,8 +18,8 @@ class C5 extends core::Object {
: self::C5::v = v, super core::Object::•()
;
constructor foo(core::int v) → self::C5
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Couldn't find constructor 'C5'.
: invalid-initializer "pkg/front_end/testcases/primary_constructors/redirecting_error.dart:6:19: Error: Can't use 'new' because it is declared more than once.
C5.foo(int v) : this(v);
^^^^"
^"
;
}
@@ -502,7 +502,7 @@ enum NoConstructorCalls {
// [analyzer] COMPILE_TIME_ERROR.REDIRECT_GENERATIVE_TO_NON_GENERATIVE_CONSTRUCTOR
// ^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.REDIRECT_TO_NON_CONST_CONSTRUCTOR
// [cfe] Couldn't find constructor 'NoConstructorCalls.factory'.
// [cfe] Generative constructors can't redirect to a factory constructor.
factory NoConstructorCalls.factory() => e1; // Valid.
@@ -61,8 +61,6 @@ extension type ET2.named(int x) {
class C3(int x) {
C3.other(int x) : this(x);
// ^
// [cfe] Couldn't find constructor 'C3'.
factory C3(int x) => C3.other(x);
// ^^
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR
@@ -71,8 +69,6 @@ class C3(int x) {
class C4.named(int x) {
C4.other(int x) : this.named(x);
// ^
// [cfe] Couldn't find constructor 'C4.named'.
factory C4.named(int x) => C4.other(x);
// ^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.DUPLICATE_CONSTRUCTOR