Skip to content

Commit 41e04fc

Browse files
johnniwintherCommit Queue
authored and
Commit Queue
committed
[cfe] Handle non-const records in const constructors
The initializer was built in an 'inferred' rather than a 'required' constant context, meaning that it would be encoded as a declaratively constant literal instead of a structurally constant literal. Closes #50132 Change-Id: I58b995d879efd2ec374b711718b63ac8f122bcfc Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/262349 Commit-Queue: Johnni Winther <[email protected]> Reviewed-by: Chloe Stefantsova <[email protected]>
1 parent 3d7aacd commit 41e04fc

File tree

35 files changed

+797
-119
lines changed

35 files changed

+797
-119
lines changed

pkg/front_end/lib/src/fasta/source/diet_listener.dart

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -771,7 +771,7 @@ class DietListener extends StackListenerImpl {
771771
TypeInferrer typeInferrer = typeInferenceEngine.createLocalTypeInferrer(
772772
uri, thisType, libraryBuilder, inferenceDataForTesting);
773773
ConstantContext constantContext = builder.isConstructor && builder.isConst
774-
? ConstantContext.inferred
774+
? ConstantContext.required
775775
: ConstantContext.none;
776776
return createListenerInternal(
777777
builder,

pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.expect

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ library /*isNonNullableByDefault*/;
77
// const var4 = C();
88
// ^
99
//
10+
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:12: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// return Simple2(this.name);
13+
// ^^^^^^^
14+
//
1015
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
1116
// Try removing the return type.
1217
// return Simple2(this.name);

pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.strong.transformed.expect

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ library /*isNonNullableByDefault*/;
77
// const var4 = C();
88
// ^
99
//
10+
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:12: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// return Simple2(this.name);
13+
// ^^^^^^^
14+
//
1015
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
1116
// Try removing the return type.
1217
// return Simple2(this.name);

pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.expect

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ library /*isNonNullableByDefault*/;
77
// const var4 = C();
88
// ^
99
//
10+
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:12: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// return Simple2(this.name);
13+
// ^^^^^^^
14+
//
1015
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
1116
// Try removing the return type.
1217
// return Simple2(this.name);

pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.modular.expect

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ library /*isNonNullableByDefault*/;
77
// const var4 = C();
88
// ^
99
//
10+
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:12: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// return Simple2(this.name);
13+
// ^^^^^^^
14+
//
1015
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
1116
// Try removing the return type.
1217
// return Simple2(this.name);

pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart.weak.transformed.expect

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@ library /*isNonNullableByDefault*/;
77
// const var4 = C();
88
// ^
99
//
10+
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:12: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// return Simple2(this.name);
13+
// ^^^^^^^
14+
//
1015
// pkg/front_end/testcases/const_functions/const_functions_const_ctor_error.dart:26:5: Error: Constructors can't have a return type.
1116
// Try removing the return type.
1217
// return Simple2(this.name);
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
// Copyright (c) 2022, the Dart project authors. Please see the AUTHORS file
2+
// for details. All rights reserved. Use of this source code is governed by a
3+
// BSD-style license that can be found in the LICENSE file.
4+
5+
class Class1 {
6+
final field;
7+
8+
const Class1() : field = []; // Error
9+
}
10+
11+
class Class2 {
12+
final field;
13+
14+
const Class2() : field = const []; // Ok
15+
}
16+
17+
class Class3 {
18+
final field;
19+
20+
const Class3() : field = Class2(); // Error
21+
}
22+
23+
class Class4 {
24+
final field;
25+
26+
const Class4() : field = const Class2(); // Ok
27+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Class1 {
2+
final field;
3+
const Class1() : field = [];
4+
}
5+
6+
class Class2 {
7+
final field;
8+
const Class2() : field = const [];
9+
}
10+
11+
class Class3 {
12+
final field;
13+
const Class3() : field = Class2();
14+
}
15+
16+
class Class4 {
17+
final field;
18+
const Class4() : field = const Class2();
19+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
class Class1 {
2+
const Class1() : field = [];
3+
final field;
4+
}
5+
6+
class Class2 {
7+
const Class2() : field = const [];
8+
final field;
9+
}
10+
11+
class Class3 {
12+
const Class3() : field = Class2();
13+
final field;
14+
}
15+
16+
class Class4 {
17+
const Class4() : field = const Class2();
18+
final field;
19+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:8:28: Error: Constant expression expected.
6+
// Try inserting 'const'.
7+
// const Class1() : field = []; // Error
8+
// ^
9+
//
10+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:20:28: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// const Class3() : field = Class2(); // Error
13+
// ^^^^^^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
class Class1 extends core::Object /*hasConstConstructor*/ {
19+
final field dynamic field;
20+
const constructor •() → self::Class1
21+
: self::Class1::field = <dynamic>[], super core::Object::•()
22+
;
23+
}
24+
class Class2 extends core::Object /*hasConstConstructor*/ {
25+
final field dynamic field;
26+
const constructor •() → self::Class2
27+
: self::Class2::field = #C1, super core::Object::•()
28+
;
29+
}
30+
class Class3 extends core::Object /*hasConstConstructor*/ {
31+
final field dynamic field;
32+
const constructor •() → self::Class3
33+
: self::Class3::field = #C2, super core::Object::•()
34+
;
35+
}
36+
class Class4 extends core::Object /*hasConstConstructor*/ {
37+
final field dynamic field;
38+
const constructor •() → self::Class4
39+
: self::Class4::field = #C2, super core::Object::•()
40+
;
41+
}
42+
43+
constants {
44+
#C1 = <dynamic>[]
45+
#C2 = self::Class2 {field:#C1}
46+
}
47+
48+
49+
Constructor coverage from constants:
50+
org-dartlang-testcase:///inferred_const_initializer.dart:
51+
- Class2. (from org-dartlang-testcase:///inferred_const_initializer.dart:14:9)
52+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:8:28: Error: Constant expression expected.
6+
// Try inserting 'const'.
7+
// const Class1() : field = []; // Error
8+
// ^
9+
//
10+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:20:28: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// const Class3() : field = Class2(); // Error
13+
// ^^^^^^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
class Class1 extends core::Object /*hasConstConstructor*/ {
19+
final field dynamic field;
20+
const constructor •() → self::Class1
21+
: self::Class1::field = <dynamic>[], super core::Object::•()
22+
;
23+
}
24+
class Class2 extends core::Object /*hasConstConstructor*/ {
25+
final field dynamic field;
26+
const constructor •() → self::Class2
27+
: self::Class2::field = #C1, super core::Object::•()
28+
;
29+
}
30+
class Class3 extends core::Object /*hasConstConstructor*/ {
31+
final field dynamic field;
32+
const constructor •() → self::Class3
33+
: self::Class3::field = #C2, super core::Object::•()
34+
;
35+
}
36+
class Class4 extends core::Object /*hasConstConstructor*/ {
37+
final field dynamic field;
38+
const constructor •() → self::Class4
39+
: self::Class4::field = #C2, super core::Object::•()
40+
;
41+
}
42+
43+
constants {
44+
#C1 = <dynamic>[]
45+
#C2 = self::Class2 {field:#C1}
46+
}
47+
48+
49+
Constructor coverage from constants:
50+
org-dartlang-testcase:///inferred_const_initializer.dart:
51+
- Class2. (from org-dartlang-testcase:///inferred_const_initializer.dart:14:9)
52+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:8:28: Error: Constant expression expected.
6+
// Try inserting 'const'.
7+
// const Class1() : field = []; // Error
8+
// ^
9+
//
10+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:20:28: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// const Class3() : field = Class2(); // Error
13+
// ^^^^^^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
class Class1 extends core::Object /*hasConstConstructor*/ {
19+
final field dynamic field;
20+
const constructor •() → self::Class1
21+
: self::Class1::field = <dynamic>[], super core::Object::•()
22+
;
23+
}
24+
class Class2 extends core::Object /*hasConstConstructor*/ {
25+
final field dynamic field;
26+
const constructor •() → self::Class2
27+
: self::Class2::field = const <dynamic>[], super core::Object::•()
28+
;
29+
}
30+
class Class3 extends core::Object /*hasConstConstructor*/ {
31+
final field dynamic field;
32+
const constructor •() → self::Class3
33+
: self::Class3::field = const self::Class2::•(), super core::Object::•()
34+
;
35+
}
36+
class Class4 extends core::Object /*hasConstConstructor*/ {
37+
final field dynamic field;
38+
const constructor •() → self::Class4
39+
: self::Class4::field = const self::Class2::•(), super core::Object::•()
40+
;
41+
}
42+
43+
44+
Extra constant evaluation status:
45+
Evaluated: ListLiteral @ org-dartlang-testcase:///inferred_const_initializer.dart:14:28 -> ListConstant(const <dynamic>[])
46+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///inferred_const_initializer.dart:20:28 -> InstanceConstant(const Class2{Class2.field: const <dynamic>[]})
47+
Evaluated: ConstructorInvocation @ org-dartlang-testcase:///inferred_const_initializer.dart:26:34 -> InstanceConstant(const Class2{Class2.field: const <dynamic>[]})
48+
Extra constant evaluation: evaluated: 4, effectively constant: 3
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
library /*isNonNullableByDefault*/;
2+
//
3+
// Problems in library:
4+
//
5+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:8:28: Error: Constant expression expected.
6+
// Try inserting 'const'.
7+
// const Class1() : field = []; // Error
8+
// ^
9+
//
10+
// pkg/front_end/testcases/general/constants/inferred_const_initializer.dart:20:28: Error: Constant expression expected.
11+
// Try inserting 'const'.
12+
// const Class3() : field = Class2(); // Error
13+
// ^^^^^^
14+
//
15+
import self as self;
16+
import "dart:core" as core;
17+
18+
class Class1 extends core::Object /*hasConstConstructor*/ {
19+
final field dynamic field;
20+
const constructor •() → self::Class1
21+
: self::Class1::field = core::_GrowableList::•<dynamic>(0), super core::Object::•()
22+
;
23+
}
24+
class Class2 extends core::Object /*hasConstConstructor*/ {
25+
final field dynamic field;
26+
const constructor •() → self::Class2
27+
: self::Class2::field = #C1, super core::Object::•()
28+
;
29+
}
30+
class Class3 extends core::Object /*hasConstConstructor*/ {
31+
final field dynamic field;
32+
const constructor •() → self::Class3
33+
: self::Class3::field = #C2, super core::Object::•()
34+
;
35+
}
36+
class Class4 extends core::Object /*hasConstConstructor*/ {
37+
final field dynamic field;
38+
const constructor •() → self::Class4
39+
: self::Class4::field = #C2, super core::Object::•()
40+
;
41+
}
42+
43+
constants {
44+
#C1 = <dynamic>[]
45+
#C2 = self::Class2 {field:#C1}
46+
}
47+
48+
49+
Constructor coverage from constants:
50+
org-dartlang-testcase:///inferred_const_initializer.dart:
51+
- Class2. (from org-dartlang-testcase:///inferred_const_initializer.dart:14:9)
52+
- Object. (from org-dartlang-sdk:///sdk/lib/core/object.dart)

0 commit comments

Comments
 (0)