Version 2.15.0-168.0.dev
Merge commit '8c41cc95378475755d530f10011a434f536d4141' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
index c2abc80..6f0eed7 100644
--- a/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
+++ b/pkg/analyzer/lib/src/dart/constant/potentially_constant.dart
@@ -244,6 +244,10 @@
if (element is MethodElement && element.isStatic) {
return;
}
+ if (element is TypeParameterElement &&
+ featureSet.isEnabled(Feature.constructor_tearoffs)) {
+ return;
+ }
nodes.add(node);
}
diff --git a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
index e9e0a9a..0d881c1 100644
--- a/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
+++ b/pkg/analyzer/test/src/dart/constant/potentially_constant_test.dart
@@ -13,7 +13,6 @@
defineReflectiveSuite(() {
defineReflectiveTests(IsConstantTypeExpressionTest);
defineReflectiveTests(PotentiallyConstantTest);
- defineReflectiveTests(PotentiallyConstantWithoutNullSafetyTest);
});
}
@@ -216,6 +215,18 @@
''', () => _xInitializer());
}
+ test_asExpression_typeParameter_29() async {
+ await _assertNotConst(r'''
+// @dart = 2.9
+const a = 0;
+class A<T> {
+ m() {
+ var x = a as T;
+ }
+}
+''', () => _xInitializer(), () => [findNode.namedType('T;')]);
+ }
+
test_asExpression_typeParameter_nested() async {
await _assertConst(r'''
const a = 0;
@@ -518,6 +529,18 @@
''', () => _xInitializer());
}
+ test_isExpression_typeParameter_29() async {
+ await _assertNotConst(r'''
+// @dart = 2.9
+const a = 0;
+class A<T> {
+ m() {
+ var x = a is T;
+ }
+}
+''', () => _xInitializer(), () => [findNode.namedType('T;')]);
+ }
+
test_isExpression_typeParameter_nested() async {
await _assertConst(r'''
const a = 0;
@@ -1097,6 +1120,25 @@
''', () => _xInitializer());
}
+ test_simpleIdentifier_typeParameter_class() async {
+ await _assertConst(r'''
+class A<T> {
+ final Object f;
+ A() : f = T;
+}
+''', () => findNode.simple('T;'));
+ }
+
+ test_simpleIdentifier_typeParameter_class_214() async {
+ await _assertNotConst(r'''
+// @dart = 2.14
+class A<T> {
+ final Object f;
+ A() : f = T;
+}
+''', () => findNode.simple('T;'), () => [findNode.simple('T;')]);
+ }
+
test_spreadElement() async {
await _assertConst(r'''
const a = [0, 1, 2];
@@ -1162,46 +1204,3 @@
return findNode.variableDeclaration('x = ').initializer!;
}
}
-
-@reflectiveTest
-class PotentiallyConstantWithoutNullSafetyTest extends PubPackageResolutionTest
- with WithoutNullSafetyMixin {
- test_asExpression_typeParameter() async {
- await _assertNotConst(r'''
-const a = 0;
-class A<T> {
- m() {
- var x = a as T;
- }
-}
-''', () => _xInitializer(), () => [findNode.namedType('T;')]);
- }
-
- test_isExpression_typeParameter() async {
- await _assertNotConst(r'''
-const a = 0;
-class A<T> {
- m() {
- var x = a is T;
- }
-}
-''', () => _xInitializer(), () => [findNode.namedType('T;')]);
- }
-
- _assertNotConst(String code, AstNode Function() getNode,
- List<AstNode> Function() getNotConstList) async {
- await resolveTestCode(code);
- var node = getNode();
- var notConstList = getNotPotentiallyConstants(
- node,
- featureSet: featureSet,
- );
-
- var expectedNotConst = getNotConstList();
- expect(notConstList, unorderedEquals(expectedNotConst));
- }
-
- Expression _xInitializer() {
- return findNode.variableDeclaration('x = ').initializer!;
- }
-}
diff --git a/runtime/tests/vm/dart/aot_prefer_equality_comparison_il_test.dart b/runtime/tests/vm/dart/aot_prefer_equality_comparison_il_test.dart
new file mode 100644
index 0000000..9baf000
--- /dev/null
+++ b/runtime/tests/vm/dart/aot_prefer_equality_comparison_il_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Test that we emit EqualityCompare rather than StrictCompare+BoxInt64
+// when comparing non-nullable integer to a Smi.
+
+// MatchIL[AOT]=factorial
+// __ GraphEntry
+// __ FunctionEntry
+// __ CheckStackOverflow
+// __ Branch(EqualityCompare)
+@pragma('vm:never-inline')
+int factorial(int value) => value == 1 ? value : value * factorial(value - 1);
+
+void main() {
+ print(factorial(4));
+}
diff --git a/runtime/tests/vm/dart_2/aot_prefer_equality_comparison_il_test.dart b/runtime/tests/vm/dart_2/aot_prefer_equality_comparison_il_test.dart
new file mode 100644
index 0000000..9baf000
--- /dev/null
+++ b/runtime/tests/vm/dart_2/aot_prefer_equality_comparison_il_test.dart
@@ -0,0 +1,18 @@
+// 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.
+
+// Test that we emit EqualityCompare rather than StrictCompare+BoxInt64
+// when comparing non-nullable integer to a Smi.
+
+// MatchIL[AOT]=factorial
+// __ GraphEntry
+// __ FunctionEntry
+// __ CheckStackOverflow
+// __ Branch(EqualityCompare)
+@pragma('vm:never-inline')
+int factorial(int value) => value == 1 ? value : value * factorial(value - 1);
+
+void main() {
+ print(factorial(4));
+}
diff --git a/runtime/vm/compiler/aot/aot_call_specializer.cc b/runtime/vm/compiler/aot/aot_call_specializer.cc
index 6fa1d01..a013cb2 100644
--- a/runtime/vm/compiler/aot/aot_call_specializer.cc
+++ b/runtime/vm/compiler/aot/aot_call_specializer.cc
@@ -465,23 +465,35 @@
switch (op_kind) {
case Token::kEQ:
- case Token::kNE:
- if (left_type->IsNull() || left_type->IsNullableSmi() ||
- right_type->IsNull() || right_type->IsNullableSmi()) {
+ case Token::kNE: {
+ // If both arguments are nullable Smi or one of the arguments is
+ // a null or Smi and the other argument is nullable then emit
+ // StrictCompare (all arguments are going to be boxed anyway).
+ // Otherwise prefer EqualityCompare to avoid redundant boxing.
+ const bool left_is_null_or_smi =
+ left_type->IsNull() || left_type->IsNullableSmi();
+ const bool right_is_null_or_smi =
+ right_type->IsNull() || right_type->IsNullableSmi();
+ const bool both_are_nullable_smis =
+ left_type->IsNullableSmi() && right_type->IsNullableSmi();
+ const bool either_can_be_null =
+ left_type->is_nullable() || right_type->is_nullable();
+ if (both_are_nullable_smis ||
+ ((left_is_null_or_smi || right_is_null_or_smi) &&
+ either_can_be_null)) {
replacement = new (Z) StrictCompareInstr(
instr->source(),
(op_kind == Token::kEQ) ? Token::kEQ_STRICT : Token::kNE_STRICT,
left_value->CopyWithType(Z), right_value->CopyWithType(Z),
/*needs_number_check=*/false, DeoptId::kNone);
} else {
- const bool null_aware =
- left_type->is_nullable() || right_type->is_nullable();
replacement = new (Z) EqualityCompareInstr(
instr->source(), op_kind, left_value->CopyWithType(Z),
right_value->CopyWithType(Z), kMintCid, DeoptId::kNone,
- null_aware, Instruction::kNotSpeculative);
+ /*null_aware=*/either_can_be_null, Instruction::kNotSpeculative);
}
break;
+ }
case Token::kLT:
case Token::kLTE:
case Token::kGT:
diff --git a/tools/VERSION b/tools/VERSION
index d113f0b..0fdd90e 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
MAJOR 2
MINOR 15
PATCH 0
-PRERELEASE 167
+PRERELEASE 168
PRERELEASE_PATCH 0
\ No newline at end of file