[cfe] Const constructors enabled with const functions.

Change-Id: Ic0597bf7ec69811ec822539ef5df1e24ef1b9884
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194560
Reviewed-by: Jake Macdonald <jakemac@google.com>
Reviewed-by: Bob Nystrom <rnystrom@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
Kallen Tu 2021-04-09 21:10:53 +00:00 committed by commit-bot@chromium.org
parent c745c6d26a
commit 0b175ed534
20 changed files with 824 additions and 5 deletions

View file

@ -1050,6 +1050,27 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
'No valid constant returned from the execution of $statement.');
}
/// Returns [null] on success and an error-"constant" on failure, as such the
/// return value should be checked.
AbortConstant executeConstructorBody(Constructor constructor) {
final Statement body = constructor.function.body;
StatementConstantEvaluator statementEvaluator =
new StatementConstantEvaluator(this);
ExecutionStatus status = body.accept(statementEvaluator);
if (status is AbortStatus) {
return status.error;
} else if (status is ReturnStatus) {
if (status.value == null) return null;
// Should not be reachable.
return createInvalidExpressionConstant(
constructor, "Constructors can't have a return value.");
} else if (status is! ProceedStatus) {
return createInvalidExpressionConstant(
constructor, "Invalid execution status of constructor body.");
}
return null;
}
/// Create an error-constant indicating that an error has been detected during
/// constant evaluation.
AbortConstant createErrorConstant(TreeNode node, Message message,
@ -1508,7 +1529,8 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
node, 'Non-const constructor invocation.');
}
if (constructor.function.body != null &&
constructor.function.body is! EmptyStatement) {
constructor.function.body is! EmptyStatement &&
!enableConstFunctions) {
// Probably unreachable.
return createInvalidExpressionConstant(
node,
@ -1822,6 +1844,12 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
for (UnevaluatedConstant constant in env.unevaluatedUnreadConstants) {
instanceBuilder.unusedArguments.add(extract(constant));
}
if (enableConstFunctions && constructor.function != null) {
AbortConstant error = executeConstructorBody(constructor);
if (error != null) return error;
}
return null;
});
}
@ -3441,6 +3469,10 @@ class StatementConstantEvaluator extends StatementVisitor<ExecutionStatus> {
return const ProceedStatus();
}
@override
ExecutionStatus visitEmptyStatement(EmptyStatement node) =>
const ProceedStatus();
@override
ExecutionStatus visitFunctionDeclaration(FunctionDeclaration node) {
final EvaluationEnvironment newEnv =
@ -3514,8 +3546,13 @@ class StatementConstantEvaluator extends StatementVisitor<ExecutionStatus> {
}
@override
ExecutionStatus visitReturnStatement(ReturnStatement node) =>
new ReturnStatus(evaluate(node.expression));
ExecutionStatus visitReturnStatement(ReturnStatement node) {
Constant result;
if (node.expression != null) {
result = evaluate(node.expression);
}
return new ReturnStatus(result);
}
@override
ExecutionStatus visitSwitchStatement(SwitchStatement node) {

View file

@ -1176,7 +1176,9 @@ class OutlineBuilder extends StackListenerImpl {
declarationBuilder.resolveTypes(typeVariables, libraryBuilder);
if (constructorName != null) {
if (isConst && bodyKind != MethodBody.Abstract) {
if (isConst &&
bodyKind != MethodBody.Abstract &&
!libraryBuilder.enableConstFunctionsInLibrary) {
addProblem(messageConstConstructorWithBody, varFinalOrConstOffset, 5);
modifiers &= ~constMask;
}

View file

@ -0,0 +1,28 @@
// Copyright (c) 2021, 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.
// Tests const constructors with a body which are enabled with const functions.
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
class Simple {
final String name;
const Simple(this.name) {
assert(this.name == printString);
}
}
const var2 = A();
class A {
const A() {
return;
}
}
void main() {
Expect.equals(var1.name, printString);
}

View file

@ -0,0 +1,39 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
return;
}
}
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
constants {
#C1 = "print"
#C2 = self::Simple {name:#C1}
#C3 = self::A {}
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor.dart:14:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor.dart:21:9)

View file

@ -0,0 +1,39 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
return;
}
}
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
constants {
#C1 = "print"
#C2 = self::Simple {name:#C1}
#C3 = self::A {}
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor.dart:14:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor.dart:21:9)

View file

@ -0,0 +1,12 @@
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
class Simple {
final String name;
const Simple(this.name) {}
}
const var2 = A();
class A {
const A() {}
}
void main() {}

View file

@ -0,0 +1,39 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
return;
}
}
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
constants {
#C1 = "print"
#C2 = self::Simple {name:#C1}
#C3 = self::A {}
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor.dart:14:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor.dart:21:9)

View file

@ -0,0 +1,28 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•()
;
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•()
;
}
static const field core::String printString = "print";
static const field self::Simple var1 = const self::Simple::•(self::printString);
static const field self::A var2 = const self::A::•();
static method main() → void
;
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor.dart:10:14 -> InstanceConstant(const Simple{Simple.name: "print"})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor.dart:19:14 -> InstanceConstant(const A{})
Extra constant evaluation: evaluated: 3, effectively constant: 2

View file

@ -0,0 +1,39 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart" as exp;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
return;
}
}
static const field core::String printString = #C1;
static const field self::Simple var1 = #C2;
static const field self::A var2 = #C3;
static method main() → void {
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
}
constants {
#C1 = "print"
#C2 = self::Simple {name:#C1}
#C3 = self::A {}
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor.dart:14:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor.dart:21:9)

View file

@ -0,0 +1,41 @@
// Copyright (c) 2021, 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.
// Tests erroneous const constructors with a body which are enabled with const
// functions.
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
class Simple {
final String name;
const Simple(this.name) {
assert(this.name != printString);
}
}
const var2 = Simple2(printString);
class Simple2 {
final String name;
const Simple2(this.name) {
return Simple2(this.name);
}
}
const var3 = B();
class A {
const A() {
assert(1 == 2);
}
}
class B extends A {
const B() : super();
}
void main() {}

View file

@ -0,0 +1,83 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:14: Error: Constant evaluation error:
// const var1 = Simple(printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:17:22: Context: This assertion failed.
// assert(this.name != printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:7: Context: While analyzing:
// const var1 = Simple(printString);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:14: Error: Constant evaluation error:
// const var3 = B();
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:33:14: Context: This assertion failed.
// assert(1 == 2);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:7: Context: While analyzing:
// const var3 = B();
// ^
//
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(!this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class Simple2 extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple2
: self::Simple2::name = name, super core::Object::•() {
invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
assert(1.{core::num::==}(2));
}
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B
: super self::A::•()
;
}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
static method main() → void {}
constants {
#C1 = "print"
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor_error.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:16:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- Simple2. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:25:9)
- B. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:38:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:32:9)

View file

@ -0,0 +1,87 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:14: Error: Constant evaluation error:
// const var1 = Simple(printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:17:22: Context: This assertion failed.
// assert(this.name != printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:7: Context: While analyzing:
// const var1 = Simple(printString);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:14: Error: Constant evaluation error:
// const var3 = B();
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:33:14: Context: This assertion failed.
// assert(1 == 2);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:7: Context: While analyzing:
// const var3 = B();
// ^
//
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(!this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class Simple2 extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple2
: self::Simple2::name = name, super core::Object::•() {
invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
assert(1.{core::num::==}(2));
}
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B
: super self::A::•()
;
}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
static method main() → void {}
constants {
#C1 = "print"
}
Extra constant evaluation status:
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_const_ctor_error.dart:33:14 -> BoolConstant(false)
Extra constant evaluation: evaluated: 7, effectively constant: 1
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor_error.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:16:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- Simple2. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:25:9)
- B. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:38:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:32:9)

View file

@ -0,0 +1,20 @@
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
class Simple {
final String name;
const Simple(this.name) {}
}
const var2 = Simple2(printString);
class Simple2 {
final String name;
const Simple2(this.name) {}
}
const var3 = B();
class A {
const A() {}
}
class B extends A {
const B() : super();
}
void main() {}

View file

@ -0,0 +1,83 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:14: Error: Constant evaluation error:
// const var1 = Simple(printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:17:22: Context: This assertion failed.
// assert(this.name != printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:7: Context: While analyzing:
// const var1 = Simple(printString);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:14: Error: Constant evaluation error:
// const var3 = B();
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:33:14: Context: This assertion failed.
// assert(1 == 2);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:7: Context: While analyzing:
// const var3 = B();
// ^
//
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(!this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class Simple2 extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple2
: self::Simple2::name = name, super core::Object::•() {
invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
assert(1.{core::num::==}(2));
}
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B
: super self::A::•()
;
}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
static method main() → void {}
constants {
#C1 = "print"
}
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor_error.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:16:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- Simple2. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:25:9)
- B. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:38:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:32:9)

View file

@ -0,0 +1,41 @@
library /*isNonNullableByDefault*/;
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•()
;
}
class Simple2 extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple2
: self::Simple2::name = name, super core::Object::•()
;
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•()
;
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B
: super self::A::•()
;
}
static const field core::String printString = "print";
static const field self::Simple var1 = const self::Simple::•(self::printString);
static const field self::Simple2 var2 = const self::Simple2::•(self::printString);
static const field self::B var3 = const self::B::•();
static method main() → void
;
Extra constant evaluation status:
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor_error.dart:12:14 -> InstanceConstant(const Simple{Simple.name: "print"})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor_error.dart:21:14 -> InstanceConstant(const Simple2{Simple2.name: "print"})
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///const_functions_const_ctor_error.dart:30:14 -> InstanceConstant(const B{})
Extra constant evaluation: evaluated: 5, effectively constant: 3

View file

@ -0,0 +1,87 @@
library /*isNonNullableByDefault*/;
//
// Problems in library:
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
// Try removing the return type.
// return Simple2(this.name);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:14: Error: Constant evaluation error:
// const var1 = Simple(printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:17:22: Context: This assertion failed.
// assert(this.name != printString);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:12:7: Context: While analyzing:
// const var1 = Simple(printString);
// ^
//
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:14: Error: Constant evaluation error:
// const var3 = B();
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:33:14: Context: This assertion failed.
// assert(1 == 2);
// ^
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:30:7: Context: While analyzing:
// const var3 = B();
// ^
//
import self as self;
import "dart:core" as core;
import "package:expect/expect.dart";
class Simple extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple
: self::Simple::name = name, super core::Object::•() {
assert(!this.{self::Simple::name}.{core::String::==}(#C1));
}
}
class Simple2 extends core::Object /*hasConstConstructor*/ {
final field core::String name;
const constructor •(core::String name) → self::Simple2
: self::Simple2::name = name, super core::Object::•() {
invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
}
}
class A extends core::Object /*hasConstConstructor*/ {
const constructor •() → self::A
: super core::Object::•() {
assert(1.{core::num::==}(2));
}
}
class B extends self::A /*hasConstConstructor*/ {
const constructor •() → self::B
: super self::A::•()
;
}
static const field core::String printString = #C1;
static const field self::Simple var1 = invalid-expression "This assertion failed.";
static const field self::Simple2 var2 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
Try removing the return type.
return Simple2(this.name);
^";
static const field self::B var3 = invalid-expression "This assertion failed.";
static method main() → void {}
constants {
#C1 = "print"
}
Extra constant evaluation status:
Evaluated: MethodInvocation @ org-dartlang-testcase:///const_functions_const_ctor_error.dart:33:14 -> BoolConstant(false)
Extra constant evaluation: evaluated: 7, effectively constant: 1
Constructor coverage from constants:
org-dartlang-testcase:///const_functions_const_ctor_error.dart:
- Simple. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:16:9)
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart:25:9)
- Simple2. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:25:9)
- B. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:38:9)
- A. (from org-dartlang-testcase:///const_functions_const_ctor_error.dart:32:9)

View file

@ -20,9 +20,11 @@ regress/issue_39035.crash: EmptyOutput
regress/issue_39091_2: EmptyOutput
regress/utf_16_le_content.crash: EmptyOutput
const_functions/const_functions_const_ctor: FormatterCrash
const_functions/const_functions_const_ctor_error: FormatterCrash
const_functions/const_functions_const_factory: FormatterCrash
dart2js/late_fields: FormatterCrash
dart2js/late_statics: FormatterCrash
const_functions/const_functions_const_factory: FormatterCrash
extensions/extension_constructor: FormatterCrash
extensions/extension_field_with_type_parameter_usage: FormatterCrash
extensions/issue38600: FormatterCrash

View file

@ -0,0 +1,23 @@
// Copyright (c) 2021, 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.
// Tests const constructors with a body are disabled without const functions.
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
// ^
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
class Simple {
final String name;
const Simple(this.name) {
//^
// [cfe] A const constructor can't have a body.
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
assert(this.name == printString);
}
}

View file

@ -0,0 +1,55 @@
// Copyright (c) 2021, 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.
// Tests erroneous const constructors with a body which are enabled with const
// functions.
// SharedOptions=--enable-experiment=const-functions
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
// ^
// [cfe] Constant evaluation error:
class Simple {
final String name;
const Simple(this.name) {
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
assert(this.name != printString);
}
}
const var2 = Simple2(printString);
class Simple2 {
final String name;
const Simple2(this.name) {
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
return Simple2(this.name);
// ^
// [cfe] Constructors can't have a return type.
// ^^^^^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.RETURN_IN_GENERATIVE_CONSTRUCTOR
}
}
const var3 = B();
// ^
// [cfe] Constant evaluation error:
class A {
const A() {
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
assert(1 == 2);
}
}
class B extends A {
const B() : super();
}

View file

@ -0,0 +1,34 @@
// Copyright (c) 2021, 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.
// Tests const constructors with a body which are enabled with const functions.
// SharedOptions=--enable-experiment=const-functions
import "package:expect/expect.dart";
const printString = "print";
const var1 = Simple(printString);
class Simple {
final String name;
const Simple(this.name) {
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
assert(this.name == printString);
}
}
const var2 = A();
class A {
const A() {
// ^
// [analyzer] SYNTACTIC_ERROR.CONST_CONSTRUCTOR_WITH_BODY
return;
}
}
void main() {
Expect.equals(var1.name, printString);
}