Skip to content

Commit 5e5f29d

Browse files
srawlinscommit-bot@chromium.org
authored and
commit-bot@chromium.org
committed
Support Never as a type in potentially const expressions
Additionally, I see that _deferred types_ are not constant, and make great examples of non-const function references, constructor references, and type literals. Fixes language/const/constant_type_variable_test Bug: #46020, #47302 Change-Id: I9df3a9eb758d058888f7d374b76756ec1443c8d6 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/215860 Commit-Queue: Samuel Rawlins <srawlins@google.com> Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
1 parent 7990144 commit 5e5f29d

File tree

2 files changed

+69
-18
lines changed

2 files changed

+69
-18
lines changed

pkg/analyzer/lib/src/dart/constant/potentially_constant.dart

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -330,9 +330,7 @@ class _Collector {
330330
var typeArguments = node.typeArguments?.arguments;
331331
if (typeArguments != null && typeArguments.length == 1) {
332332
var elementType = typeArguments[0];
333-
// TODO(srawlins): Change to "potentially" constant type expression as
334-
// per https://github.com/dart-lang/sdk/issues/47302?
335-
if (!isConstantTypeExpression(elementType)) {
333+
if (!isPotentiallyConstantTypeExpression(elementType)) {
336334
nodes.add(elementType);
337335
}
338336
}
@@ -347,9 +345,7 @@ class _Collector {
347345
var typeArguments = node.typeArguments?.arguments;
348346
if (typeArguments != null && typeArguments.length == 1) {
349347
var elementType = typeArguments[0];
350-
// TODO(srawlins): Change to "potentially" constant type expression as
351-
// per https://github.com/dart-lang/sdk/issues/47302?
352-
if (!isConstantTypeExpression(elementType)) {
348+
if (!isPotentiallyConstantTypeExpression(elementType)) {
353349
nodes.add(elementType);
354350
}
355351
}
@@ -406,10 +402,8 @@ class _ConstantTypeChecker {
406402
}
407403
return true;
408404
}
409-
if (node.type is DynamicTypeImpl) {
410-
return true;
411-
}
412-
if (node.type is VoidType) {
405+
var type = node.type;
406+
if (type is DynamicTypeImpl || type is NeverType || type is VoidType) {
413407
return true;
414408
}
415409
return false;

pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart

Lines changed: 65 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -469,6 +469,19 @@ class B<T> {}
469469
''', () => findNode.constructorReference('B<int>.new'));
470470
}
471471

472+
test_constructorReference_explicitTypeArguments_nonConst() async {
473+
await _assertNotConst('''
474+
import '' deferred as self;
475+
class A {
476+
Object x;
477+
const A(): x = B<self.A>.new;
478+
}
479+
480+
class B<T> {}
481+
''', () => findNode.constructorReference('B<self.A>.new'),
482+
() => [findNode.typeAnnotation('self.A')]);
483+
}
484+
472485
test_constructorReference_noTypeArguments() async {
473486
await _assertConst('''
474487
class A {
@@ -491,6 +504,19 @@ X id<X>(X x) => x;
491504
''', () => findNode.functionReference('id<int>'));
492505
}
493506

507+
test_functionReference_explicitTypeArguments_nonConst() async {
508+
await _assertNotConst('''
509+
import '' deferred as self;
510+
class A {
511+
final int Function(int) x;
512+
const A(): x = id<self.A>;
513+
}
514+
515+
X id<X>(X x) => x;
516+
''', () => findNode.functionReference('id<self.A>'),
517+
() => [findNode.typeAnnotation('self.A')]);
518+
}
519+
494520
test_functionReference_noTypeArguments() async {
495521
await _assertConst('''
496522
class A {
@@ -617,20 +643,39 @@ var x = const [a, b, 2];
617643
() => [findNode.simple('a,'), findNode.simple('b,')]);
618644
}
619645

646+
test_listLiteral_ofDynamic() async {
647+
await _assertConst('''
648+
var x = const <dynamic>[];
649+
''', () => _xInitializer());
650+
}
651+
652+
test_listLiteral_ofNever() async {
653+
await _assertConst('''
654+
var x = const <Never>[];
655+
''', () => _xInitializer());
656+
}
657+
658+
test_listLiteral_ofVoid() async {
659+
await _assertConst('''
660+
var x = const <void>[];
661+
''', () => _xInitializer());
662+
}
663+
620664
test_listLiteral_typeArgument() async {
621665
await _assertConst(r'''
622666
var x = const <int>[0, 1, 2];
623667
''', () => _xInitializer());
624668
}
625669

626670
test_listLiteral_typeArgument_notConstType() async {
627-
await _assertNotConst(r'''
628-
class A<T> {
671+
await _assertNotConst('''
672+
import '' deferred as self;
673+
class A {
629674
m() {
630-
var x = const <T>[0, 1, 2];
675+
var x = const <self.A>[];
631676
}
632677
}
633-
''', () => _xInitializer(), () => [findNode.namedType('T>[0')]);
678+
''', () => _xInitializer(), () => [findNode.namedType('A>[')]);
634679
}
635680

636681
test_literal_bool() async {
@@ -1039,13 +1084,14 @@ var x = const <int>{0, 1, 2};
10391084
}
10401085

10411086
test_setLiteral_typeArgument_notConstType() async {
1042-
await _assertNotConst(r'''
1043-
class A<T> {
1087+
await _assertNotConst('''
1088+
import '' deferred as self;
1089+
class A {
10441090
m() {
1045-
var x = const <T>{0, 1, 2};
1091+
var x = const <self.A>{};
10461092
}
10471093
}
1048-
''', () => _xInitializer(), () => [findNode.namedType('T>{0')]);
1094+
''', () => _xInitializer(), () => [findNode.namedType('A>{')]);
10491095
}
10501096

10511097
test_simpleIdentifier_class() async {
@@ -1230,6 +1276,17 @@ class A {
12301276
''', () => findNode.typeLiteral('List<int>'));
12311277
}
12321278

1279+
test_typeLiteral_nonConst() async {
1280+
await _assertNotConst('''
1281+
import '' deferred as self;
1282+
class A {
1283+
Type x;
1284+
const A(): x = List<self.A>;
1285+
}
1286+
''', () => findNode.typeLiteral('List<self.A>'),
1287+
() => [findNode.typeAnnotation('self.A')]);
1288+
}
1289+
12331290
_assertConst(String code, AstNode Function() getNode) async {
12341291
await resolveTestCode(code);
12351292
var node = getNode();

0 commit comments

Comments
 (0)