Issue 51567. Implement constant equality as primitive equality

Bug: https://github.com/dart-lang/sdk/issues/51567
Change-Id: I7821598a761573519205b0ea06b13f433639282b
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/286241
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-03-01 20:58:57 +00:00 committed by Commit Queue
parent 16e935ebad
commit ad15774558
6 changed files with 374 additions and 49 deletions

View file

@ -544,6 +544,7 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
_substitution = substitution { _substitution = substitution {
_dartObjectComputer = DartObjectComputer( _dartObjectComputer = DartObjectComputer(
typeSystem, typeSystem,
_library.featureSet,
_errorReporter, _errorReporter,
); );
} }
@ -1566,11 +1567,12 @@ class ConstantVisitor extends UnifyingAstVisitor<DartObjectImpl> {
/// class and for collecting errors during evaluation. /// class and for collecting errors during evaluation.
class DartObjectComputer { class DartObjectComputer {
final TypeSystemImpl _typeSystem; final TypeSystemImpl _typeSystem;
final FeatureSet _featureSet;
/// The error reporter that we are using to collect errors. /// The error reporter that we are using to collect errors.
final ErrorReporter _errorReporter; final ErrorReporter _errorReporter;
DartObjectComputer(this._typeSystem, this._errorReporter); DartObjectComputer(this._typeSystem, this._featureSet, this._errorReporter);
DartObjectImpl? add(BinaryExpression node, DartObjectImpl? leftOperand, DartObjectImpl? add(BinaryExpression node, DartObjectImpl? leftOperand,
DartObjectImpl? rightOperand) { DartObjectImpl? rightOperand) {
@ -1698,7 +1700,7 @@ class DartObjectComputer {
DartObjectImpl? rightOperand) { DartObjectImpl? rightOperand) {
if (leftOperand != null && rightOperand != null) { if (leftOperand != null && rightOperand != null) {
try { try {
return leftOperand.equalEqual(_typeSystem, rightOperand); return leftOperand.equalEqual(_typeSystem, _featureSet, rightOperand);
} on EvaluationException catch (exception) { } on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node); _errorReporter.reportErrorForNode(exception.errorCode, node);
} }
@ -1770,7 +1772,8 @@ class DartObjectComputer {
DartObjectImpl? rightOperand) { DartObjectImpl? rightOperand) {
if (leftOperand != null && rightOperand != null) { if (leftOperand != null && rightOperand != null) {
try { try {
return leftOperand.lazyEqualEqual(_typeSystem, rightOperand); return leftOperand.lazyEqualEqual(
_typeSystem, _featureSet, rightOperand);
} on EvaluationException catch (exception) { } on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node); _errorReporter.reportErrorForNode(exception.errorCode, node);
} }
@ -1878,7 +1881,7 @@ class DartObjectComputer {
DartObjectImpl? rightOperand) { DartObjectImpl? rightOperand) {
if (leftOperand != null && rightOperand != null) { if (leftOperand != null && rightOperand != null) {
try { try {
return leftOperand.notEqual(_typeSystem, rightOperand); return leftOperand.notEqual(_typeSystem, _featureSet, rightOperand);
} on EvaluationException catch (exception) { } on EvaluationException catch (exception) {
_errorReporter.reportErrorForNode(exception.errorCode, node); _errorReporter.reportErrorForNode(exception.errorCode, node);
} }

View file

@ -429,7 +429,10 @@ class DartObjectImpl implements DartObject {
/// Throws an [EvaluationException] if the operator is not appropriate for an /// Throws an [EvaluationException] if the operator is not appropriate for an
/// object of this kind. /// object of this kind.
DartObjectImpl equalEqual( DartObjectImpl equalEqual(
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) { TypeSystemImpl typeSystem,
FeatureSet featureSet,
DartObjectImpl rightOperand,
) {
if (isNull || rightOperand.isNull) { if (isNull || rightOperand.isNull) {
return DartObjectImpl( return DartObjectImpl(
typeSystem, typeSystem,
@ -439,12 +442,22 @@ class DartObjectImpl implements DartObject {
: BoolState.FALSE_STATE, : BoolState.FALSE_STATE,
); );
} }
if (isBoolNumStringOrNull) { if (featureSet.isEnabled(Feature.patterns)) {
return DartObjectImpl( if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
typeSystem, return DartObjectImpl(
typeSystem.typeProvider.boolType, typeSystem,
state.equalEqual(typeSystem, rightOperand.state), typeSystem.typeProvider.boolType,
); state.equalEqual(typeSystem, rightOperand.state),
);
}
} else {
if (isBoolNumStringOrNull) {
return DartObjectImpl(
typeSystem,
typeSystem.typeProvider.boolType,
state.equalEqual(typeSystem, rightOperand.state),
);
}
} }
throw EvaluationException( throw EvaluationException(
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
@ -598,7 +611,10 @@ class DartObjectImpl implements DartObject {
/// Throws an [EvaluationException] if the operator is not appropriate for an /// Throws an [EvaluationException] if the operator is not appropriate for an
/// object of this kind. /// object of this kind.
DartObjectImpl lazyEqualEqual( DartObjectImpl lazyEqualEqual(
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) { TypeSystemImpl typeSystem,
FeatureSet featureSet,
DartObjectImpl rightOperand,
) {
if (isNull || rightOperand.isNull) { if (isNull || rightOperand.isNull) {
return DartObjectImpl( return DartObjectImpl(
typeSystem, typeSystem,
@ -608,12 +624,22 @@ class DartObjectImpl implements DartObject {
: BoolState.FALSE_STATE, : BoolState.FALSE_STATE,
); );
} }
if (isBoolNumStringOrNull) { if (featureSet.isEnabled(Feature.patterns)) {
return DartObjectImpl( if (state is DoubleState || hasPrimitiveEquality(featureSet)) {
typeSystem, return DartObjectImpl(
typeSystem.typeProvider.boolType, typeSystem,
state.lazyEqualEqual(typeSystem, rightOperand.state), typeSystem.typeProvider.boolType,
); state.equalEqual(typeSystem, rightOperand.state),
);
}
} else {
if (isBoolNumStringOrNull) {
return DartObjectImpl(
typeSystem,
typeSystem.typeProvider.boolType,
state.equalEqual(typeSystem, rightOperand.state),
);
}
} }
throw EvaluationException( throw EvaluationException(
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING); CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING);
@ -739,8 +765,12 @@ class DartObjectImpl implements DartObject {
/// Throws an [EvaluationException] if the operator is not appropriate for an /// Throws an [EvaluationException] if the operator is not appropriate for an
/// object of this kind. /// object of this kind.
DartObjectImpl notEqual( DartObjectImpl notEqual(
TypeSystemImpl typeSystem, DartObjectImpl rightOperand) { TypeSystemImpl typeSystem,
return equalEqual(typeSystem, rightOperand).logicalNot(typeSystem); FeatureSet featureSet,
DartObjectImpl rightOperand,
) {
return equalEqual(typeSystem, featureSet, rightOperand)
.logicalNot(typeSystem);
} }
/// Return the result of converting this object to a 'String'. /// Return the result of converting this object to a 'String'.

View file

@ -29,6 +29,166 @@ main() {
@reflectiveTest @reflectiveTest
class ConstantVisitorTest extends ConstantVisitorTestSupport class ConstantVisitorTest extends ConstantVisitorTestSupport
with ConstantVisitorTestCases { with ConstantVisitorTestCases {
test_equalEqual_double_object() async {
await assertNoErrorsInCode('''
const v = 1.2 == Object();
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_int_int_false() async {
await assertNoErrorsInCode('''
const v = 1 == 2;
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_int_int_true() async {
await assertNoErrorsInCode('''
const v = 1 == 1;
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool true
''');
}
test_equalEqual_int_null() async {
await assertNoErrorsInCode('''
const int? a = 1;
const v = a == null;
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_int_object() async {
await assertNoErrorsInCode('''
const v = 1 == Object();
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_int_userClass() async {
await assertNoErrorsInCode('''
class A {
const A();
}
const v = 1 == A();
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_null_object() async {
await assertNoErrorsInCode('''
const Object? a = null;
const v = a == Object();
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_string_object() async {
await assertNoErrorsInCode('''
const v = 'foo' == Object();
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_userClass_hasEqEq() async {
await assertErrorsInCode('''
class A {
const A();
bool operator ==(other) => false;
}
const v = A() == 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 72, 8),
]);
// TODO(scheglov) check the invalid value
}
test_equalEqual_userClass_hasHashCode() async {
await assertErrorsInCode('''
class A {
const A();
int get hashCode => 0;
}
const v = A() == 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 61, 8),
]);
// TODO(scheglov) check the invalid value
}
test_equalEqual_userClass_hasPrimitiveEquality_false() async {
await assertNoErrorsInCode('''
class A {
final int f;
const A(this.f);
}
const v = A(0) == 0;
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool false
''');
}
test_equalEqual_userClass_hasPrimitiveEquality_language219() async {
await assertErrorsInCode('''
// @dart = 2.19
class A {
const A();
}
const v = A() == 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 52, 8),
]);
_evaluateConstantOrNull('v', errorCodes: [
CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING,
]);
}
test_equalEqual_userClass_hasPrimitiveEquality_true() async {
await assertNoErrorsInCode('''
class A {
final int f;
const A(this.f);
}
const v = A(0) == A(0);
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
bool true
''');
}
test_hasPrimitiveEquality_bool() async { test_hasPrimitiveEquality_bool() async {
await assertNoErrorsInCode(''' await assertNoErrorsInCode('''
const v = true; const v = true;
@ -2314,6 +2474,19 @@ const a = const A<int?>();
); );
} }
test_assertInitializer_intInDoubleContext_true() async {
await assertNoErrorsInCode('''
class A {
const A(double x): assert((x + 3) / 2 == 1.5);
}
const v = const A(0);
''');
final value = _evaluateConstant('v');
assertDartObjectText(value, r'''
A
''');
}
test_fieldInitializer_functionReference_withTypeParameter() async { test_fieldInitializer_functionReference_withTypeParameter() async {
await resolveTestCode(''' await resolveTestCode('''
void g<U>(U a) {} void g<U>(U a) {}
@ -2519,16 +2692,6 @@ const a = const A(1);
); );
} }
test_assertInitializer_intInDoubleContext_true() async {
await resolveTestCode('''
class A {
const A(double x): assert((x + 3) / 2 == 1.5);
}
const a = const A(0);
''');
_assertValidConstant('a');
}
test_assertInitializer_simple_false() async { test_assertInitializer_simple_false() async {
await resolveTestCode(''' await resolveTestCode('''
class A { class A {

View file

@ -2,6 +2,7 @@
// for details. All rights reserved. Use of this source code is governed by a // 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. // BSD-style license that can be found in the LICENSE file.
import 'package:analyzer/dart/analysis/features.dart';
import 'package:analyzer/dart/element/nullability_suffix.dart'; import 'package:analyzer/dart/element/nullability_suffix.dart';
import 'package:analyzer/dart/element/type.dart'; import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/dart/element/type_provider.dart'; import 'package:analyzer/dart/element/type_provider.dart';
@ -11,6 +12,7 @@ import 'package:test/test.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart'; import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../../../generated/test_analysis_context.dart'; import '../../../generated/test_analysis_context.dart';
import '../../../util/feature_sets.dart';
main() { main() {
defineReflectiveSuite(() { defineReflectiveSuite(() {
@ -27,6 +29,7 @@ final Matcher throwsEvaluationException =
class DartObjectImplTest { class DartObjectImplTest {
late final TypeProvider _typeProvider; late final TypeProvider _typeProvider;
late final TypeSystemImpl _typeSystem; late final TypeSystemImpl _typeSystem;
FeatureSet _featureSet = FeatureSets.latestWithExperiments;
void setUp() { void setUp() {
var analysisContext = TestAnalysisContext(); var analysisContext = TestAnalysisContext();
@ -358,14 +361,29 @@ class DartObjectImplTest {
_assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0)); _assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
} }
void test_equalEqual_double_false_language219() {
_featureSet = FeatureSets.language_2_19;
_assertEqualEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(4.0));
}
void test_equalEqual_double_true() { void test_equalEqual_double_true() {
_assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0)); _assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
} }
void test_equalEqual_double_true_language219() {
_featureSet = FeatureSets.language_2_19;
_assertEqualEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(2.0));
}
void test_equalEqual_double_unknown() { void test_equalEqual_double_unknown() {
_assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null)); _assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
} }
void test_equalEqual_double_unknown_language219() {
_featureSet = FeatureSets.language_2_19;
_assertEqualEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
}
void test_equalEqual_int_false() { void test_equalEqual_int_false() {
_assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5)); _assertEqualEqual(_boolValue(false), _intValue(-5), _intValue(5));
} }
@ -378,7 +396,8 @@ class DartObjectImplTest {
_assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3)); _assertEqualEqual(_boolValue(null), _intValue(null), _intValue(3));
} }
void test_equalEqual_list_empty() { void test_equalEqual_list_error_language219() {
_featureSet = FeatureSets.language_2_19;
_assertEqualEqual( _assertEqualEqual(
null, null,
_listValue(_typeProvider.intType, []), _listValue(_typeProvider.intType, []),
@ -386,15 +405,16 @@ class DartObjectImplTest {
); );
} }
void test_equalEqual_list_false() { void test_equalEqual_list_true() {
_assertEqualEqual( _assertEqualEqual(
null, _boolValue(true),
_listValue(_typeProvider.intType, []), _listValue(_typeProvider.intType, []),
_listValue(_typeProvider.intType, []), _listValue(_typeProvider.intType, []),
); );
} }
void test_equalEqual_map_empty() { void test_equalEqual_map_error_language219() {
_featureSet = FeatureSets.language_2_19;
_assertEqualEqual( _assertEqualEqual(
null, null,
_mapValue(_typeProvider.intType, _typeProvider.stringType, []), _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
@ -402,9 +422,9 @@ class DartObjectImplTest {
); );
} }
void test_equalEqual_map_false() { void test_equalEqual_map_true() {
_assertEqualEqual( _assertEqualEqual(
null, _boolValue(true),
_mapValue(_typeProvider.intType, _typeProvider.stringType, []), _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
_mapValue(_typeProvider.intType, _typeProvider.stringType, []), _mapValue(_typeProvider.intType, _typeProvider.stringType, []),
); );
@ -1582,11 +1602,21 @@ class DartObjectImplTest {
_assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false)); _assertNotEqual(_boolValue(null), _boolValue(null), _boolValue(false));
} }
void test_notEqual_double_false() { void test_notEqual_double_double_false() {
_assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0)); _assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
} }
void test_notEqual_double_true() { void test_notEqual_double_double_false_language219() {
_featureSet = FeatureSets.language_2_19;
_assertNotEqual(_boolValue(false), _doubleValue(2.0), _doubleValue(2.0));
}
void test_notEqual_double_double_true() {
_assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
}
void test_notEqual_double_double_true_language219() {
_featureSet = FeatureSets.language_2_19;
_assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0)); _assertNotEqual(_boolValue(true), _doubleValue(2.0), _doubleValue(4.0));
} }
@ -1594,6 +1624,11 @@ class DartObjectImplTest {
_assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null)); _assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
} }
void test_notEqual_double_unknown_language219() {
_featureSet = FeatureSets.language_2_19;
_assertNotEqual(_boolValue(null), _doubleValue(1.0), _doubleValue(null));
}
void test_notEqual_int_false() { void test_notEqual_int_false() {
_assertNotEqual(_boolValue(false), _intValue(5), _intValue(5)); _assertNotEqual(_boolValue(false), _intValue(5), _intValue(5));
} }
@ -1996,10 +2031,10 @@ class DartObjectImplTest {
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) { DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
if (expected == null) { if (expected == null) {
expect(() { expect(() {
left.equalEqual(_typeSystem, right); return left.equalEqual(_typeSystem, _featureSet, right);
}, throwsEvaluationException); }, throwsEvaluationException);
} else { } else {
DartObjectImpl result = left.equalEqual(_typeSystem, right); DartObjectImpl result = left.equalEqual(_typeSystem, _featureSet, right);
expect(result, isNotNull); expect(result, isNotNull);
expect(result, expected); expect(result, expected);
} }
@ -2189,10 +2224,10 @@ class DartObjectImplTest {
DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) { DartObjectImpl? expected, DartObjectImpl left, DartObjectImpl right) {
if (expected == null) { if (expected == null) {
expect(() { expect(() {
left.notEqual(_typeSystem, right); left.notEqual(_typeSystem, _featureSet, right);
}, throwsEvaluationException); }, throwsEvaluationException);
} else { } else {
DartObjectImpl result = left.notEqual(_typeSystem, right); DartObjectImpl result = left.notEqual(_typeSystem, _featureSet, right);
expect(result, isNotNull); expect(result, isNotNull);
expect(result, expected); expect(result, expected);
} }

View file

@ -22,6 +22,14 @@ const b = a == Object();
'''); ''');
} }
test_equal_double_object_language219() async {
await assertNoErrorsInCode(r'''
// @dart = 2.19
const a = 0.1;
const b = a == Object();
''');
}
test_equal_int_object() async { test_equal_int_object() async {
await assertNoErrorsInCode(r''' await assertNoErrorsInCode(r'''
const a = 0; const a = 0;
@ -54,8 +62,48 @@ const b = a == Object();
'''); ''');
} }
test_equal_userClass_int() async { test_equal_userClass_int_hasEqEq() async {
await assertErrorsInCode(r''' await assertErrorsInCode(r'''
class A {
const A();
bool operator ==(other) => false;
}
const a = A();
const b = a == 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 87, 6),
]);
}
test_equal_userClass_int_hasHashCode() async {
await assertErrorsInCode(r'''
class A {
const A();
int get hashCode => 0;
}
const a = A();
const b = a == 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 76, 6),
]);
}
test_equal_userClass_int_hasPrimitiveEquality() async {
await assertNoErrorsInCode(r'''
class A {
const A();
}
const a = A();
const b = a == 0;
''');
}
test_equal_userClass_int_language219() async {
await assertErrorsInCode(r'''
// @dart = 2.19
class A { class A {
const A(); const A();
} }
@ -63,7 +111,7 @@ class A {
const a = A(); const a = A();
const b = a == 0; const b = a == 0;
''', [ ''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 51, 6), error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 67, 6),
]); ]);
} }
@ -74,6 +122,14 @@ const b = a != Object();
'''); ''');
} }
test_notEqual_double_object_language219() async {
await assertNoErrorsInCode(r'''
// @dart = 2.19
const a = 0.1;
const b = a != Object();
''');
}
test_notEqual_int_object() async { test_notEqual_int_object() async {
await assertNoErrorsInCode(r''' await assertNoErrorsInCode(r'''
const a = 0; const a = 0;
@ -106,8 +162,48 @@ const b = a != Object();
'''); ''');
} }
test_notEqual_userClass_int() async { test_notEqual_userClass_int_hasEqEq() async {
await assertErrorsInCode(r''' await assertErrorsInCode(r'''
class A {
const A();
bool operator ==(other) => false;
}
const a = A();
const b = a != 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 87, 6),
]);
}
test_notEqual_userClass_int_hasHashCode() async {
await assertErrorsInCode(r'''
class A {
const A();
int get hashCode => 0;
}
const a = A();
const b = a != 0;
''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 76, 6),
]);
}
test_notEqual_userClass_int_hasPrimitiveEquality() async {
await assertNoErrorsInCode(r'''
class A {
const A();
}
const a = A();
const b = a != 0;
''');
}
test_notEqual_userClass_int_language219() async {
await assertErrorsInCode(r'''
// @dart = 2.19
class A { class A {
const A(); const A();
} }
@ -115,7 +211,7 @@ class A {
const a = A(); const a = A();
const b = a != 0; const b = a != 0;
''', [ ''', [
error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 51, 6), error(CompileTimeErrorCode.CONST_EVAL_TYPE_BOOL_NUM_STRING, 67, 6),
]); ]);
} }
} }

View file

@ -177,8 +177,6 @@ method<T>(o) {
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX // [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern. // [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
case const Object() == 2: // Error case const Object() == 2: // Error
// ^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_TYPE_BOOL_NUM_STRING
// ^ // ^
// [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX // [analyzer] SYNTACTIC_ERROR.INVALID_CONSTANT_CONST_PREFIX
// [cfe] The expression can't be prefixed by 'const' to form a constant pattern. // [cfe] The expression can't be prefixed by 'const' to form a constant pattern.
@ -243,4 +241,4 @@ method<T>(o) {
// [analyzer] COMPILE_TIME_ERROR.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION // [analyzer] COMPILE_TIME_ERROR.CONSTANT_PATTERN_WITH_NON_CONSTANT_EXPRESSION
// [cfe] Not a constant expression. // [cfe] Not a constant expression.
} }
} }