Revert "Issue 45672. Report constant errors when null value where non-nullable type is expected."

This reverts commit ac27053055.

Reason for revert: landed without necessary local changes

Original change's description:
> Issue 45672. Report constant errors when null value where non-nullable type is expected.
>
> Original: https://dart-review.googlesource.com/c/sdk/+/196042
> Reverted as: https://dart-review.googlesource.com/c/sdk/+/196281
>
> Presubmit looks green:
> https://test.corp.google.com/ui#id=OCL:369788056:BASE:369887187:1619108797262:daf61e5&include_skipped=true
>
> Bug: https://github.com/dart-lang/sdk/issues/45672
> Change-Id: I459b7ea3e1218d960583bf4b6ace5b2c40dc7f4a
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/196300
> Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
> Commit-Queue: Konstantin Shcheglov <scheglov@google.com>

TBR=scheglov@google.com,brianwilkerson@google.com

Change-Id: Ia624c5c90195fd2477b068e245a644a62795d35c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: https://github.com/dart-lang/sdk/issues/45672
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/197108
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2021-04-27 21:42:21 +00:00 committed by commit-bot@chromium.org
parent 71fc33e427
commit 3a0a196fed
10 changed files with 85 additions and 223 deletions

View file

@ -822,6 +822,9 @@ class ConstantEvaluationEngine {
DartObjectImpl obj,
DartType type,
) {
if (obj.isNull) {
return true;
}
var objType = obj.type;
return library.typeSystem.isSubtypeOf(objType, type);
}

View file

@ -50,7 +50,7 @@ class C {
"const Center(name: 'v')",
context: '''
class Align {
final double? widthFactor;
final double widthFactor;
const Align({String name, this.widthFactor})
assert(widthFactor == null || widthFactor >= 0.0);
}

View file

@ -15,7 +15,7 @@ main() {
@reflectiveTest
class ConstConstructorFieldTypeMismatchTest extends PubPackageResolutionTest {
test_generic_int_int() async {
test_assignable_generic() async {
await assertErrorsInCode(
r'''
class C<T> {
@ -31,7 +31,41 @@ var v = const C<int>();
);
}
test_generic_string_int() async {
test_assignable_nullValue() async {
await assertNoErrorsInCode(r'''
class A {
const A(x) : y = x;
final int y;
}
var v = const A(null);
''');
}
test_assignable_unresolvedFieldAndNullValue() async {
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final Unresolved y;
}
var v = const A(null);
''', [
error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
]);
}
test_notAssignable() async {
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final int y;
}
var v = const A('foo');
''', [
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 57, 14),
]);
}
test_notAssignable_generic() async {
await assertErrorsInCode(
r'''
class C<T> {
@ -49,50 +83,13 @@ var v = const C<String>();
);
}
test_notGeneric_int_int() async {
test_notAssignable_unresolved() async {
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final int y;
final Unresolved y;
}
var v = const A('foo');
''', [
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 57, 14),
]);
}
test_notGeneric_int_null() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_FIELD_TYPE_MISMATCH, 57, 13),
], legacy: []);
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final int y;
}
var v = const A(null);
''', errors);
}
test_notGeneric_unresolved_int() async {
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final Unresolved y;
}
var v = const A(0);
''', [
error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
]);
}
test_notGeneric_unresolved_null() async {
await assertErrorsInCode(r'''
class A {
const A(x) : y = x;
final Unresolved y;
}
var v = const A(null);
''', [
error(CompileTimeErrorCode.UNDEFINED_CLASS, 40, 10),
]);

View file

@ -10,19 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(ListElementTypeNotAssignableTest);
defineReflectiveTests(ListElementTypeNotAssignableWithoutNullSafetyTest);
});
}
@reflectiveTest
class ListElementTypeNotAssignableTest extends PubPackageResolutionTest
with ListElementTypeNotAssignableTestCases {
test_const_stringQuestion_null_value() async {
await assertNoErrorsInCode('''
var v = const <String?>[null];
''');
}
}
with ListElementTypeNotAssignableTestCases {}
mixin ListElementTypeNotAssignableTestCases on PubPackageResolutionTest {
test_const_ifElement_thenElseFalse_intInt() async {
@ -74,32 +67,6 @@ var v = const <int>[if (true) a];
]);
}
test_const_intInt() async {
await assertNoErrorsInCode(r'''
var v1 = <int> [42];
var v2 = const <int> [42];
''');
}
test_const_intNull_dynamic() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
], legacy: []);
await assertErrorsInCode('''
const a = null;
var v = const <int>[a];
''', errors);
}
test_const_intNull_value() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.LIST_ELEMENT_TYPE_NOT_ASSIGNABLE, 20, 4),
], legacy: []);
await assertErrorsInCode('''
var v = const <int>[null];
''', errors);
}
test_const_spread_intInt() async {
await assertNoErrorsInCode('''
var v = const <int>[...[0, 1]];
@ -123,12 +90,32 @@ var v = const <String>[x];
]);
}
test_const_stringNull() async {
await assertNoErrorsInCode('''
var v = const <String?>[null];
''');
}
test_const_stringNull_dynamic() async {
await assertNoErrorsInCode('''
const dynamic x = null;
var v = const <String>[x];
''');
}
test_const_voidInt() async {
await assertNoErrorsInCode('''
var v = const <void>[42];
''');
}
test_element_type_is_assignable() async {
await assertNoErrorsInCode(r'''
var v1 = <int> [42];
var v2 = const <int> [42];
''');
}
test_nonConst_ifElement_thenElseFalse_intDynamic() async {
await assertNoErrorsInCode('''
const dynamic a = 'a';
@ -194,8 +181,3 @@ var v = <void>[42];
''');
}
}
@reflectiveTest
class ListElementTypeNotAssignableWithoutNullSafetyTest
extends PubPackageResolutionTest
with WithoutNullSafetyMixin, ListElementTypeNotAssignableTestCases {}

View file

@ -16,20 +16,7 @@ main() {
@reflectiveTest
class MapKeyTypeNotAssignableTest extends PubPackageResolutionTest
with MapKeyTypeNotAssignableTestCases {
test_const_intQuestion_null_dynamic() async {
await assertNoErrorsInCode('''
const dynamic a = null;
var v = const <int?, bool>{a : true};
''');
}
test_const_intQuestion_null_value() async {
await assertNoErrorsInCode('''
var v = const <int?, bool>{null : true};
''');
}
}
with MapKeyTypeNotAssignableTestCases {}
mixin MapKeyTypeNotAssignableTestCases on PubPackageResolutionTest {
test_const_ifElement_thenElseFalse_intInt_dynamic() async {
@ -97,25 +84,6 @@ var v = const <int, bool>{a : true};
''');
}
test_const_intNull_dynamic() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 50, 1),
], legacy: []);
await assertErrorsInCode('''
const dynamic a = null;
var v = const <int, bool>{a : true};
''', errors);
}
test_const_intNull_value() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.MAP_KEY_TYPE_NOT_ASSIGNABLE, 26, 4),
], legacy: []);
await assertErrorsInCode('''
var v = const <int, bool>{null : true};
''', errors);
}
test_const_intString_dynamic() async {
await assertErrorsInCode('''
const dynamic a = 'a';

View file

@ -16,20 +16,7 @@ main() {
@reflectiveTest
class MapValueTypeNotAssignableTest extends PubPackageResolutionTest
with MapValueTypeNotAssignableTestCases {
test_const_intQuestion_null_dynamic() async {
await assertNoErrorsInCode('''
const dynamic a = null;
var v = const <bool, int?>{true: a};
''');
}
test_const_intQuestion_null_value() async {
await assertNoErrorsInCode('''
var v = const <bool, int?>{true: null};
''');
}
}
with MapValueTypeNotAssignableTestCases {}
mixin MapValueTypeNotAssignableTestCases on PubPackageResolutionTest {
test_const_ifElement_thenElseFalse_intInt_dynamic() async {
@ -97,25 +84,6 @@ var v = const <bool, int>{true: a};
''');
}
test_const_intNull_dynamic() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 56, 1),
], legacy: []);
await assertErrorsInCode('''
const dynamic a = null;
var v = const <bool, int>{true: a};
''', errors);
}
test_const_intNull_value() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.MAP_VALUE_TYPE_NOT_ASSIGNABLE, 32, 4),
], legacy: []);
await assertErrorsInCode('''
var v = const <bool, int>{true: null};
''', errors);
}
test_const_intString_dynamic() async {
await assertErrorsInCode('''
const dynamic a = 'a';

View file

@ -24,7 +24,6 @@ main() {
const A();
}
''', [
error(CompileTimeErrorCode.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH, 41, 9),
error(CompileTimeErrorCode.NOT_ENOUGH_POSITIONAL_ARGUMENTS, 48, 2),
]);
}

View file

@ -10,26 +10,12 @@ import '../dart/resolution/context_collection_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(SetElementTypeNotAssignableTest);
defineReflectiveTests(SetElementTypeNotAssignableWithoutNullSafetyTest);
});
}
@reflectiveTest
class SetElementTypeNotAssignableTest extends PubPackageResolutionTest
with SetElementTypeNotAssignableTestCases {
test_const_stringQuestion_null_dynamic() async {
await assertNoErrorsInCode('''
const a = null;
var v = const <String?>{a};
''');
}
test_const_stringQuestion_null_value() async {
await assertNoErrorsInCode('''
var v = const <String?>{null};
''');
}
}
with SetElementTypeNotAssignableTestCases {}
mixin SetElementTypeNotAssignableTestCases on PubPackageResolutionTest {
test_const_ifElement_thenElseFalse_intInt() async {
@ -81,61 +67,44 @@ var v = const <int>{if (true) a};
]);
}
test_const_intInt_dynamic() async {
test_const_spread_intInt() async {
await assertNoErrorsInCode('''
const dynamic a = 42;
var v = const <int>{a};
var v = const <int>{...[0, 1]};
''');
}
test_const_intInt_value() async {
test_explicitTypeArgs_const() async {
await assertErrorsInCode('''
var v = const <String>{42};
''', [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 23, 2),
]);
}
test_explicitTypeArgs_const_actualTypeMatch() async {
await assertNoErrorsInCode('''
var v = const <int>{42};
const dynamic x = null;
var v = const <String>{x};
''');
}
test_const_intNull_dynamic() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 36, 1),
], legacy: []);
test_explicitTypeArgs_const_actualTypeMismatch() async {
await assertErrorsInCode('''
const a = null;
var v = const <int>{a};
''', errors);
}
test_const_intNull_value() async {
var errors = expectedErrorsByNullability(nullable: [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 20, 4),
], legacy: []);
await assertErrorsInCode('''
var v = const <int>{null};
''', errors);
}
test_const_intString_dynamic() async {
await assertErrorsInCode('''
const dynamic x = 'abc';
var v = const <int>{x};
const dynamic x = 42;
var v = const <String>{x};
''', [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 45, 1),
]);
}
test_const_intString_value() async {
test_explicitTypeArgs_notConst() async {
await assertErrorsInCode('''
var v = const <int>{'abc'};
var v = <String>{42};
''', [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 20, 5),
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 17, 2),
]);
}
test_const_spread_intInt() async {
await assertNoErrorsInCode('''
var v = const <int>{...[0, 1]};
''');
}
test_nonConst_ifElement_thenElseFalse_intDynamic() async {
await assertNoErrorsInCode('''
const dynamic a = 'a';
@ -179,24 +148,4 @@ var v = <int>{if (true) a};
var v = <int>{...[0, 1]};
''');
}
test_notConst_intString_dynamic() async {
await assertNoErrorsInCode('''
const dynamic x = 'abc';
var v = <int>{x};
''');
}
test_notConst_intString_value() async {
await assertErrorsInCode('''
var v = <int>{'abc'};
''', [
error(CompileTimeErrorCode.SET_ELEMENT_TYPE_NOT_ASSIGNABLE, 14, 5),
]);
}
}
@reflectiveTest
class SetElementTypeNotAssignableWithoutNullSafetyTest
extends PubPackageResolutionTest
with WithoutNullSafetyMixin, SetElementTypeNotAssignableTestCases {}

View file

@ -18,6 +18,4 @@ class C extends Base {
main() {
const C("str");
//^^^^^^^^^^^^^^
// [analyzer] COMPILE_TIME_ERROR.CONST_EVAL_THROWS_EXCEPTION
}

View file

@ -12,8 +12,6 @@ class A {
class StringInterpolation1NegativeTest {
// Dollar not followed by "{" or identifier.
static const DOLLAR = const A("$");
// [error line 14, column 33, length 3]
// [analyzer] COMPILE_TIME_ERROR.CONST_CONSTRUCTOR_PARAM_TYPE_MISMATCH
// [error line 14, column 35, length 0]
// [analyzer] COMPILE_TIME_ERROR.CONST_INITIALIZED_WITH_NON_CONSTANT_VALUE
// [cfe] A '$' has special meaning inside a string, and must be followed by an identifier or an expression in curly braces ({}).