mirror of
https://github.com/dart-lang/sdk
synced 2024-09-16 04:06:59 +00:00
Insert implicit downcast checks for the expressions in a map literal.
Tests that have begun failing due to this change are marked with a reference to issue #31402. Change-Id: I40b4b45d5ea32dc34aee68bfe39912141e4d7d35 Reviewed-on: https://dart-review.googlesource.com/22806 Reviewed-by: Konstantin Shcheglov <scheglov@google.com> Commit-Queue: Paul Berry <paulberry@google.com>
This commit is contained in:
parent
6d4661e527
commit
ffdae2fd4d
|
@ -1209,6 +1209,11 @@ class ShadowMapLiteral extends MapLiteral implements ShadowExpression {
|
|||
List<DartType> actualTypes;
|
||||
assert((_declaredKeyType == null) == (_declaredValueType == null));
|
||||
bool inferenceNeeded = _declaredKeyType == null && inferrer.strongMode;
|
||||
bool typeChecksNeeded = !inferrer.isTopLevel;
|
||||
if (inferenceNeeded || typeChecksNeeded) {
|
||||
formalTypes = [];
|
||||
actualTypes = [];
|
||||
}
|
||||
if (inferenceNeeded) {
|
||||
inferredTypes = [const UnknownType(), const UnknownType()];
|
||||
inferrer.typeSchemaEnvironment.inferGenericFunctionOrType(mapType,
|
||||
|
@ -1216,23 +1221,21 @@ class ShadowMapLiteral extends MapLiteral implements ShadowExpression {
|
|||
isConst: isConst);
|
||||
inferredKeyType = inferredTypes[0];
|
||||
inferredValueType = inferredTypes[1];
|
||||
formalTypes = [];
|
||||
actualTypes = [];
|
||||
} else {
|
||||
inferredKeyType = _declaredKeyType ?? const DynamicType();
|
||||
inferredValueType = _declaredValueType ?? const DynamicType();
|
||||
}
|
||||
if (inferenceNeeded || !inferrer.isTopLevel) {
|
||||
if (inferenceNeeded || typeChecksNeeded) {
|
||||
for (var entry in entries) {
|
||||
var keyType = inferrer.inferExpression(
|
||||
entry.key, inferredKeyType, inferenceNeeded);
|
||||
var valueType = inferrer.inferExpression(
|
||||
entry.value, inferredValueType, inferenceNeeded);
|
||||
entry.key, inferredKeyType, inferenceNeeded || typeChecksNeeded);
|
||||
var valueType = inferrer.inferExpression(entry.value, inferredValueType,
|
||||
inferenceNeeded || typeChecksNeeded);
|
||||
if (inferenceNeeded) {
|
||||
formalTypes.addAll(mapType.typeArguments);
|
||||
actualTypes.add(keyType);
|
||||
actualTypes.add(valueType);
|
||||
}
|
||||
actualTypes.add(keyType);
|
||||
actualTypes.add(valueType);
|
||||
}
|
||||
}
|
||||
if (inferenceNeeded) {
|
||||
|
@ -1254,6 +1257,17 @@ class ShadowMapLiteral extends MapLiteral implements ShadowExpression {
|
|||
keyType = inferredKeyType;
|
||||
valueType = inferredValueType;
|
||||
}
|
||||
if (typeChecksNeeded) {
|
||||
for (int i = 0; i < entries.length; i++) {
|
||||
var entry = entries[i];
|
||||
var key = entry.key;
|
||||
inferrer.checkAssignability(
|
||||
keyType, actualTypes[2 * i], key, key.fileOffset);
|
||||
var value = entry.value;
|
||||
inferrer.checkAssignability(
|
||||
valueType, actualTypes[2 * i + 1], value, value.fileOffset);
|
||||
}
|
||||
}
|
||||
var inferredType = typeNeeded
|
||||
? new InterfaceType(mapClass, [inferredKeyType, inferredValueType])
|
||||
: null;
|
||||
|
|
|
@ -12,7 +12,7 @@ void foo(
|
|||
/*error:MAP_KEY_TYPE_NOT_ASSIGNABLE,error:MAP_KEY_TYPE_NOT_ASSIGNABLE*/ "hello":
|
||||
"world"
|
||||
}]) {}
|
||||
void main() {
|
||||
void test() {
|
||||
{
|
||||
Map<int, String> l0 = /*@typeArgs=int, String*/ {};
|
||||
Map<int, String> l1 = /*@typeArgs=int, String*/ {3: "hello"};
|
||||
|
@ -90,3 +90,5 @@ void main() {
|
|||
};
|
||||
}
|
||||
}
|
||||
|
||||
main() {}
|
||||
|
|
|
@ -3,7 +3,7 @@ import self as self;
|
|||
import "dart:core" as core;
|
||||
|
||||
static method foo([core::Map<core::int, core::String> m1 = const <dynamic, dynamic>{1: "hello"}, core::Map<core::int, core::String> m2 = const <dynamic, dynamic>{"hello": "world"}]) → void {}
|
||||
static method main() → void {
|
||||
static method test() → void {
|
||||
{
|
||||
core::Map<core::int, core::String> l0 = <dynamic, dynamic>{};
|
||||
core::Map<core::int, core::String> l1 = <dynamic, dynamic>{3: "hello"};
|
||||
|
@ -45,3 +45,4 @@ static method main() → void {
|
|||
const core::Map<core::int, core::String> l4 = const <dynamic, dynamic>{3: "hello", "hello": 3};
|
||||
}
|
||||
}
|
||||
static method main() → dynamic {}
|
||||
|
|
|
@ -2,14 +2,14 @@ library test;
|
|||
import self as self;
|
||||
import "dart:core" as core;
|
||||
|
||||
static method foo([core::Map<core::int, core::String> m1 = const <core::int, core::String>{1: "hello"}, core::Map<core::int, core::String> m2 = const <core::int, core::String>{"hello": "world"}]) → void {}
|
||||
static method main() → void {
|
||||
static method foo([core::Map<core::int, core::String> m1 = const <core::int, core::String>{1: "hello"}, core::Map<core::int, core::String> m2 = const <core::int, core::String>{"hello" as{TypeError} core::int: "world"}]) → void {}
|
||||
static method test() → void {
|
||||
{
|
||||
core::Map<core::int, core::String> l0 = <core::int, core::String>{};
|
||||
core::Map<core::int, core::String> l1 = <core::int, core::String>{3: "hello"};
|
||||
core::Map<core::int, core::String> l2 = <core::int, core::String>{"hello": "hello"};
|
||||
core::Map<core::int, core::String> l3 = <core::int, core::String>{3: 3};
|
||||
core::Map<core::int, core::String> l4 = <core::int, core::String>{3: "hello", "hello": 3};
|
||||
core::Map<core::int, core::String> l2 = <core::int, core::String>{"hello" as{TypeError} core::int: "hello"};
|
||||
core::Map<core::int, core::String> l3 = <core::int, core::String>{3: 3 as{TypeError} core::String};
|
||||
core::Map<core::int, core::String> l4 = <core::int, core::String>{3: "hello", "hello" as{TypeError} core::int: 3 as{TypeError} core::String};
|
||||
}
|
||||
{
|
||||
core::Map<dynamic, dynamic> l0 = <dynamic, dynamic>{};
|
||||
|
@ -22,15 +22,15 @@ static method main() → void {
|
|||
core::Map<dynamic, core::String> l0 = <dynamic, core::String>{};
|
||||
core::Map<dynamic, core::String> l1 = <dynamic, core::String>{3: "hello"};
|
||||
core::Map<dynamic, core::String> l2 = <dynamic, core::String>{"hello": "hello"};
|
||||
core::Map<dynamic, core::String> l3 = <dynamic, core::String>{3: 3};
|
||||
core::Map<dynamic, core::String> l4 = <dynamic, core::String>{3: "hello", "hello": 3};
|
||||
core::Map<dynamic, core::String> l3 = <dynamic, core::String>{3: 3 as{TypeError} core::String};
|
||||
core::Map<dynamic, core::String> l4 = <dynamic, core::String>{3: "hello", "hello": 3 as{TypeError} core::String};
|
||||
}
|
||||
{
|
||||
core::Map<core::int, dynamic> l0 = <core::int, dynamic>{};
|
||||
core::Map<core::int, dynamic> l1 = <core::int, dynamic>{3: "hello"};
|
||||
core::Map<core::int, dynamic> l2 = <core::int, dynamic>{"hello": "hello"};
|
||||
core::Map<core::int, dynamic> l2 = <core::int, dynamic>{"hello" as{TypeError} core::int: "hello"};
|
||||
core::Map<core::int, dynamic> l3 = <core::int, dynamic>{3: 3};
|
||||
core::Map<core::int, dynamic> l4 = <core::int, dynamic>{3: "hello", "hello": 3};
|
||||
core::Map<core::int, dynamic> l4 = <core::int, dynamic>{3: "hello", "hello" as{TypeError} core::int: 3};
|
||||
}
|
||||
{
|
||||
core::Map<core::int, core::String> l0 = <core::num, dynamic>{} as{TypeError} core::Map<core::int, core::String>;
|
||||
|
@ -40,8 +40,9 @@ static method main() → void {
|
|||
{
|
||||
const core::Map<core::int, core::String> l0 = const <core::int, core::String>{};
|
||||
const core::Map<core::int, core::String> l1 = const <core::int, core::String>{3: "hello"};
|
||||
const core::Map<core::int, core::String> l2 = const <core::int, core::String>{"hello": "hello"};
|
||||
const core::Map<core::int, core::String> l3 = const <core::int, core::String>{3: 3};
|
||||
const core::Map<core::int, core::String> l4 = const <core::int, core::String>{3: "hello", "hello": 3};
|
||||
const core::Map<core::int, core::String> l2 = const <core::int, core::String>{"hello" as{TypeError} core::int: "hello"};
|
||||
const core::Map<core::int, core::String> l3 = const <core::int, core::String>{3: 3 as{TypeError} core::String};
|
||||
const core::Map<core::int, core::String> l4 = const <core::int, core::String>{3: "hello", "hello" as{TypeError} core::int: 3 as{TypeError} core::String};
|
||||
}
|
||||
}
|
||||
static method main() → dynamic {}
|
||||
|
|
|
@ -21,6 +21,6 @@ static method getResource(core::String str) → self::Resource
|
|||
return null;
|
||||
static method main() → dynamic {
|
||||
core::Map<core::String, core::List<self::Folder>> map = <core::String, core::List<self::Folder>>{"pkgA": <self::Folder>[self::getResource("/pkgA/lib/") as{TypeError} self::Folder], "pkgB": <self::Folder>[self::getResource("/pkgB/lib/") as{TypeError} self::Folder]};
|
||||
core::List<core::Map<core::String, self::Folder>> list = <core::Map<core::String, self::Folder>>[<core::String, self::Folder>{"pkgA": self::getResource("/pkgA/lib/")}, <core::String, self::Folder>{"pkgB": self::getResource("/pkgB/lib/")}];
|
||||
core::List<core::Map<core::String, self::Folder>> list = <core::Map<core::String, self::Folder>>[<core::String, self::Folder>{"pkgA": self::getResource("/pkgA/lib/") as{TypeError} self::Folder}, <core::String, self::Folder>{"pkgB": self::getResource("/pkgB/lib/") as{TypeError} self::Folder}];
|
||||
self::Foo<core::List<self::Folder>> foo = new self::Foo::•<core::List<self::Folder>>(<self::Folder>[self::getResource("/pkgA/lib/") as{TypeError} self::Folder]);
|
||||
}
|
||||
|
|
|
@ -77,7 +77,6 @@ inference/downwards_inference_on_function_expressions: TypeCheckError
|
|||
inference/downwards_inference_on_function_of_t_using_the_t: Fail # Issue #29798
|
||||
inference/downwards_inference_on_generic_function_expressions: TypeCheckError
|
||||
inference/downwards_inference_on_list_literals_infer_downwards: RuntimeError
|
||||
inference/downwards_inference_on_map_literals: TypeCheckError
|
||||
inference/downwards_inference_yield_yield_star: TypeCheckError
|
||||
inference/future_then_2: TypeCheckError
|
||||
inference/future_then_4: TypeCheckError
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
// Copyright (c) 2017, 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.
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
class A {}
|
||||
|
||||
class B extends A {}
|
||||
|
||||
void main() {
|
||||
A a1 = new B();
|
||||
A a2 = new A();
|
||||
<B, Object>{a1: 1}; // No error
|
||||
<Object, B>{1: a1}; // No error
|
||||
Expect.throwsTypeError(() {
|
||||
<B, Object>{a2: 1};
|
||||
});
|
||||
Expect.throwsTypeError(() {
|
||||
<Object, B>{1: a2};
|
||||
});
|
||||
}
|
|
@ -1074,6 +1074,7 @@ implicit_downcast_during_compound_assignment_test: RuntimeError
|
|||
implicit_downcast_during_conditional_expression_test: RuntimeError
|
||||
implicit_downcast_during_if_null_assignment_test: RuntimeError
|
||||
implicit_downcast_during_invocation_test: RuntimeError
|
||||
implicit_downcast_during_map_literal_test: RuntimeError
|
||||
implicit_downcast_during_variable_declaration_test: RuntimeError
|
||||
inferrer_synthesized_constructor_test: RuntimeError
|
||||
malformed2_test/00: MissingCompileTimeError
|
||||
|
@ -2976,6 +2977,7 @@ implicit_downcast_during_combiner_test: RuntimeError
|
|||
implicit_downcast_during_compound_assignment_test: RuntimeError
|
||||
implicit_downcast_during_conditional_expression_test: RuntimeError
|
||||
implicit_downcast_during_if_null_assignment_test: RuntimeError
|
||||
implicit_downcast_during_map_literal_test: RuntimeError
|
||||
implicit_downcast_during_variable_declaration_test: RuntimeError
|
||||
|
||||
[ $compiler == dart2js && $dart2js_with_kernel && $checked ]
|
||||
|
|
|
@ -105,6 +105,7 @@ built_in_identifier_type_annotation_test/68: MissingCompileTimeError # Issue 288
|
|||
call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
|
||||
call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
|
||||
call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
|
||||
call_function2_test: CompileTimeError # Issue 31402 (map literal)
|
||||
call_function_apply_test: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
call_function_test: CompileTimeError
|
||||
call_non_method_field_test/01: MissingCompileTimeError
|
||||
|
@ -834,15 +835,11 @@ malformed_test/23: MissingCompileTimeError
|
|||
malformed_test/24: MissingCompileTimeError
|
||||
malformed_type_test: MissingCompileTimeError
|
||||
many_generic_instanceof_test: RuntimeError
|
||||
map_literal1_test/01: MissingCompileTimeError
|
||||
map_literal3_test/01: MissingCompileTimeError
|
||||
map_literal3_test/02: MissingCompileTimeError
|
||||
map_literal3_test/03: MissingCompileTimeError
|
||||
map_literal3_test/04: MissingCompileTimeError
|
||||
map_literal4_test/01: MissingCompileTimeError
|
||||
map_literal4_test/02: MissingCompileTimeError
|
||||
map_literal4_test/03: MissingCompileTimeError
|
||||
map_literal4_test/04: MissingCompileTimeError
|
||||
map_literal4_test/06: MissingCompileTimeError
|
||||
method_override2_test/00: MissingCompileTimeError
|
||||
method_override2_test/01: MissingCompileTimeError
|
||||
|
@ -1684,6 +1681,7 @@ built_in_identifier_type_annotation_test/74: MissingCompileTimeError # Issue 288
|
|||
call_constructor_on_unresolvable_class_test/01: MissingCompileTimeError
|
||||
call_constructor_on_unresolvable_class_test/02: MissingCompileTimeError
|
||||
call_constructor_on_unresolvable_class_test/03: MissingCompileTimeError
|
||||
call_function2_test: CompileTimeError # Issue 31402 (map literal)
|
||||
call_function_apply_test: CompileTimeError # Issue 31402 (Invocation arguments)
|
||||
call_function_test: CompileTimeError
|
||||
call_non_method_field_test/01: MissingCompileTimeError
|
||||
|
@ -2328,6 +2326,7 @@ implicit_downcast_during_compound_assignment_test: Pass # Correctly passes.
|
|||
implicit_downcast_during_conditional_expression_test: Pass # Correctly passes.
|
||||
implicit_downcast_during_if_null_assignment_test: Pass # Correctly passes.
|
||||
implicit_downcast_during_list_literal_test: Pass # Correctly passes.
|
||||
implicit_downcast_during_map_literal_test: Pass # Correctly passes.
|
||||
implicit_downcast_during_variable_declaration_test: Pass # Correctly passes.
|
||||
implicit_this_test/01: MissingCompileTimeError
|
||||
implicit_this_test/02: MissingCompileTimeError
|
||||
|
@ -2500,15 +2499,11 @@ malformed_test/24: MissingCompileTimeError
|
|||
malformed_type_test: MissingCompileTimeError
|
||||
many_generic_instanceof_test: RuntimeError
|
||||
many_overridden_no_such_method_test: SkipByDesign
|
||||
map_literal1_test/01: MissingCompileTimeError
|
||||
map_literal3_test/01: MissingCompileTimeError
|
||||
map_literal3_test/02: MissingCompileTimeError
|
||||
map_literal3_test/03: MissingCompileTimeError
|
||||
map_literal3_test/04: MissingCompileTimeError
|
||||
map_literal4_test/01: MissingCompileTimeError
|
||||
map_literal4_test/02: MissingCompileTimeError
|
||||
map_literal4_test/03: MissingCompileTimeError
|
||||
map_literal4_test/04: MissingCompileTimeError
|
||||
map_literal4_test/06: MissingCompileTimeError
|
||||
map_literal8_test: Pass
|
||||
map_literal8_test: RuntimeError
|
||||
|
@ -3347,6 +3342,7 @@ implicit_downcast_during_compound_assignment_test: RuntimeError
|
|||
implicit_downcast_during_conditional_expression_test: RuntimeError
|
||||
implicit_downcast_during_if_null_assignment_test: RuntimeError
|
||||
implicit_downcast_during_list_literal_test: RuntimeError
|
||||
implicit_downcast_during_map_literal_test: RuntimeError
|
||||
implicit_downcast_during_variable_declaration_test: RuntimeError
|
||||
mixin_forwarding_constructor4_test/01: MissingCompileTimeError # KernelVM bug: Issue 15101
|
||||
mixin_forwarding_constructor4_test/02: MissingCompileTimeError # KernelVM bug: Issue 15101
|
||||
|
|
|
@ -1035,6 +1035,7 @@ implicit_downcast_during_conditional_expression_test: RuntimeError
|
|||
implicit_downcast_during_if_null_assignment_test: RuntimeError
|
||||
implicit_downcast_during_invocation_test: RuntimeError
|
||||
implicit_downcast_during_list_literal_test: RuntimeError
|
||||
implicit_downcast_during_map_literal_test: RuntimeError
|
||||
implicit_downcast_during_variable_declaration_test: RuntimeError
|
||||
tearoff_dynamic_test: RuntimeError
|
||||
type_argument_in_super_type_test: RuntimeError
|
||||
|
|
|
@ -1005,6 +1005,7 @@ implicit_downcast_during_compound_assignment_test: RuntimeError
|
|||
implicit_downcast_during_conditional_expression_test: RuntimeError
|
||||
implicit_downcast_during_if_null_assignment_test: RuntimeError
|
||||
implicit_downcast_during_list_literal_test: RuntimeError
|
||||
implicit_downcast_during_map_literal_test: RuntimeError
|
||||
implicit_downcast_during_variable_declaration_test: RuntimeError
|
||||
|
||||
[ $runtime == vm && $checked && $mode == debug && $compiler != dartk ]
|
||||
|
|
Loading…
Reference in a new issue