mirror of
https://github.com/dart-lang/sdk
synced 2024-11-02 12:24:24 +00:00
[cfe] Allow non-const constructor invocations in const functions.
Change-Id: Ieb8d3030c6132ccf9037e64cef3ba6c4eeaa90ea Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/197180 Reviewed-by: Jake Macdonald <jakemac@google.com> Reviewed-by: Dmitry Stefantsov <dmitryas@google.com> Commit-Queue: Kallen Tu <kallentu@google.com>
This commit is contained in:
parent
83a957f9bd
commit
4e2fac951d
17 changed files with 123 additions and 2 deletions
|
@ -1444,7 +1444,7 @@ class ConstantEvaluator implements ExpressionVisitor<Constant> {
|
|||
|
||||
@override
|
||||
Constant visitConstructorInvocation(ConstructorInvocation node) {
|
||||
if (!node.isConst) {
|
||||
if (!node.isConst && !enableConstFunctions) {
|
||||
return createInvalidExpressionConstant(
|
||||
node, 'Non-constant constructor invocation "$node".');
|
||||
}
|
||||
|
|
|
@ -23,6 +23,9 @@ class A {
|
|||
}
|
||||
}
|
||||
|
||||
const var3 = fn();
|
||||
A fn() => A();
|
||||
|
||||
void main() {
|
||||
Expect.equals(var1.name, printString);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ class A extends core::Object /*hasConstConstructor*/ {
|
|||
static const field core::String printString = #C1;
|
||||
static const field self::Simple var1 = #C2;
|
||||
static const field self::A var2 = #C3;
|
||||
static const field self::A var3 = #C3;
|
||||
static method fn() → self::A
|
||||
return new self::A::•();
|
||||
static method main() → void {
|
||||
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
|
||||
}
|
||||
|
|
|
@ -21,6 +21,9 @@ class A extends core::Object /*hasConstConstructor*/ {
|
|||
static const field core::String printString = #C1;
|
||||
static const field self::Simple var1 = #C2;
|
||||
static const field self::A var2 = #C3;
|
||||
static const field self::A var3 = #C3;
|
||||
static method fn() → self::A
|
||||
return new self::A::•();
|
||||
static method main() → void {
|
||||
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
|
||||
}
|
||||
|
|
|
@ -9,4 +9,6 @@ const var2 = A();
|
|||
class A {
|
||||
const A() {}
|
||||
}
|
||||
const var3 = fn();
|
||||
A fn() => A();
|
||||
void main() {}
|
||||
|
|
|
@ -21,6 +21,9 @@ class A extends core::Object /*hasConstConstructor*/ {
|
|||
static const field core::String printString = #C1;
|
||||
static const field self::Simple var1 = #C2;
|
||||
static const field self::A var2 = #C3;
|
||||
static const field self::A var3 = #C3;
|
||||
static method fn() → self::A
|
||||
return new self::A::•();
|
||||
static method main() → void {
|
||||
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
|
||||
}
|
||||
|
|
|
@ -18,6 +18,9 @@ class A extends core::Object /*hasConstConstructor*/ {
|
|||
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 const field self::A var3 = self::fn();
|
||||
static method fn() → self::A
|
||||
;
|
||||
static method main() → void
|
||||
;
|
||||
|
||||
|
@ -25,4 +28,4 @@ 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
|
||||
Extra constant evaluation: evaluated: 4, effectively constant: 2
|
||||
|
|
|
@ -21,6 +21,9 @@ class A extends core::Object /*hasConstConstructor*/ {
|
|||
static const field core::String printString = #C1;
|
||||
static const field self::Simple var1 = #C2;
|
||||
static const field self::A var2 = #C3;
|
||||
static const field self::A var3 = #C3;
|
||||
static method fn() → self::A
|
||||
return new self::A::•();
|
||||
static method main() → void {
|
||||
exp::Expect::equals((#C2).{self::Simple::name}, #C1);
|
||||
}
|
||||
|
|
|
@ -38,4 +38,9 @@ class B extends A {
|
|||
const B() : super();
|
||||
}
|
||||
|
||||
const var4 = C();
|
||||
class C {
|
||||
int? x;
|
||||
}
|
||||
|
||||
void main() {}
|
||||
|
|
|
@ -2,6 +2,11 @@ library /*isNonNullableByDefault*/;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const var4 = C();
|
||||
// ^
|
||||
//
|
||||
// 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);
|
||||
|
@ -60,6 +65,12 @@ class B extends self::A /*hasConstConstructor*/ {
|
|||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
field core::int? x = null;
|
||||
synthetic constructor •() → self::C
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
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.
|
||||
|
@ -67,6 +78,10 @@ Try removing the return type.
|
|||
return Simple2(this.name);
|
||||
^";
|
||||
static const field self::B var3 = invalid-expression "This assertion failed.";
|
||||
static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const var4 = C();
|
||||
^";
|
||||
static method main() → void {}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -2,6 +2,11 @@ library /*isNonNullableByDefault*/;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const var4 = C();
|
||||
// ^
|
||||
//
|
||||
// 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);
|
||||
|
@ -60,6 +65,12 @@ class B extends self::A /*hasConstConstructor*/ {
|
|||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
field core::int? x = null;
|
||||
synthetic constructor •() → self::C
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
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.
|
||||
|
@ -67,6 +78,10 @@ Try removing the return type.
|
|||
return Simple2(this.name);
|
||||
^";
|
||||
static const field self::B var3 = invalid-expression "This assertion failed.";
|
||||
static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const var4 = C();
|
||||
^";
|
||||
static method main() → void {}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -17,4 +17,8 @@ class A {
|
|||
class B extends A {
|
||||
const B() : super();
|
||||
}
|
||||
const var4 = C();
|
||||
class C {
|
||||
int? x;
|
||||
}
|
||||
void main() {}
|
||||
|
|
|
@ -2,6 +2,11 @@ library /*isNonNullableByDefault*/;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const var4 = C();
|
||||
// ^
|
||||
//
|
||||
// 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);
|
||||
|
@ -60,6 +65,12 @@ class B extends self::A /*hasConstConstructor*/ {
|
|||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
field core::int? x = null;
|
||||
synthetic constructor •() → self::C
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
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.
|
||||
|
@ -67,6 +78,10 @@ Try removing the return type.
|
|||
return Simple2(this.name);
|
||||
^";
|
||||
static const field self::B var3 = invalid-expression "This assertion failed.";
|
||||
static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const var4 = C();
|
||||
^";
|
||||
static method main() → void {}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -1,4 +1,12 @@
|
|||
library /*isNonNullableByDefault*/;
|
||||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const var4 = C();
|
||||
// ^
|
||||
//
|
||||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
|
@ -26,10 +34,19 @@ class B extends self::A /*hasConstConstructor*/ {
|
|||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
field core::int? x;
|
||||
synthetic constructor •() → self::C
|
||||
;
|
||||
}
|
||||
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 const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const var4 = C();
|
||||
^";
|
||||
static method main() → void
|
||||
;
|
||||
|
||||
|
|
|
@ -2,6 +2,11 @@ library /*isNonNullableByDefault*/;
|
|||
//
|
||||
// Problems in library:
|
||||
//
|
||||
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
// Try using a constructor or factory that is 'const'.
|
||||
// const var4 = C();
|
||||
// ^
|
||||
//
|
||||
// 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);
|
||||
|
@ -60,6 +65,12 @@ class B extends self::A /*hasConstConstructor*/ {
|
|||
: super self::A::•()
|
||||
;
|
||||
}
|
||||
class C extends core::Object {
|
||||
field core::int? x = null;
|
||||
synthetic constructor •() → self::C
|
||||
: super core::Object::•()
|
||||
;
|
||||
}
|
||||
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.
|
||||
|
@ -67,6 +78,10 @@ Try removing the return type.
|
|||
return Simple2(this.name);
|
||||
^";
|
||||
static const field self::B var3 = invalid-expression "This assertion failed.";
|
||||
static const field dynamic var4 = invalid-expression "pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:41:14: Error: Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
Try using a constructor or factory that is 'const'.
|
||||
const var4 = C();
|
||||
^";
|
||||
static method main() → void {}
|
||||
|
||||
constants {
|
||||
|
|
|
@ -53,3 +53,13 @@ class A {
|
|||
class B extends A {
|
||||
const B() : super();
|
||||
}
|
||||
|
||||
const var4 = C();
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_WITH_NON_CONST
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
// [cfe] Cannot invoke a non-'const' constructor where a const expression is expected.
|
||||
class C {
|
||||
int? x;
|
||||
}
|
||||
|
|
|
@ -29,6 +29,11 @@ class A {
|
|||
}
|
||||
}
|
||||
|
||||
const var3 = fn();
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
|
||||
A fn() => A();
|
||||
|
||||
void main() {
|
||||
Expect.equals(var1.name, printString);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue