Resolve type parameters to bounds when checking for implementing Iterable / Map.

R=brianwilkerson@google.com

Change-Id: Ifdb8fe73cbe731bfe5e3ea130f846fabfc1ce07f
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/138565
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov
2020-03-06 02:36:21 +00:00
committed by commit-bot@chromium.org
parent a410f5bde1
commit ce7fcff2ea
3 changed files with 90 additions and 0 deletions
@@ -142,6 +142,8 @@ class LiteralElementVerifier {
return;
}
expressionType = typeSystem.resolveToBound(expressionType);
InterfaceType iterableType;
if (expressionType is InterfaceTypeImpl) {
iterableType = expressionType.asInstanceOf(typeProvider.iterableElement);
@@ -183,6 +185,8 @@ class LiteralElementVerifier {
return;
}
expressionType = typeSystem.resolveToBound(expressionType);
InterfaceType mapType;
if (expressionType is InterfaceTypeImpl) {
mapType = expressionType.asInstanceOf(typeProvider.mapElement);
@@ -2,7 +2,9 @@
// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
@@ -10,9 +12,30 @@ import '../dart/resolution/driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NotIterableSpreadTest);
defineReflectiveTests(NotIterableSpreadNullSafetyTest);
});
}
@reflectiveTest
class NotIterableSpreadNullSafetyTest extends NotIterableSpreadTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
..contextFeatures = FeatureSet.forTesting(
sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
@override
bool get typeToStringWithNullability => true;
test_iterable_typeParameter_bound_listQuestion() async {
await assertNoErrorsInCode('''
void f<T extends List<int>?>(T a) {
var v = [...?a];
v;
}
''');
}
}
@reflectiveTest
class NotIterableSpreadTest extends DriverResolutionTest {
test_iterable_list() async {
@@ -28,6 +51,15 @@ var v = [...?null];
''');
}
test_iterable_typeParameter_bound_list() async {
await assertNoErrorsInCode('''
void f<T extends List<int>>(T a) {
var v = [...a];
v;
}
''');
}
test_notIterable_direct() async {
await assertErrorsInCode('''
var a = 0;
@@ -64,4 +96,15 @@ var v = [if (1 > 0) ...a];
error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 34, 1),
]);
}
test_notIterable_typeParameter_bound() async {
await assertErrorsInCode('''
void f<T extends num>(T a) {
var v = [...a];
v;
}
''', [
error(CompileTimeErrorCode.NOT_ITERABLE_SPREAD, 43, 1),
]);
}
}
@@ -2,7 +2,9 @@
// 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:analyzer/dart/analysis/features.dart';
import 'package:analyzer/src/error/codes.dart';
import 'package:analyzer/src/generated/engine.dart';
import 'package:test_reflective_loader/test_reflective_loader.dart';
import '../dart/resolution/driver_resolution.dart';
@@ -10,9 +12,30 @@ import '../dart/resolution/driver_resolution.dart';
main() {
defineReflectiveSuite(() {
defineReflectiveTests(NotMapSpreadTest);
defineReflectiveTests(NotMapSpreadNullSafetyTest);
});
}
@reflectiveTest
class NotMapSpreadNullSafetyTest extends NotMapSpreadTest {
@override
AnalysisOptionsImpl get analysisOptions => AnalysisOptionsImpl()
..contextFeatures = FeatureSet.forTesting(
sdkVersion: '2.7.0', additionalFeatures: [Feature.non_nullable]);
@override
bool get typeToStringWithNullability => true;
test_map_typeParameter_bound_mapQuestion() async {
await assertNoErrorsInCode('''
void f<T extends Map<int, String>?>(T a) {
var v = <int, String>{...?a};
v;
}
''');
}
}
@reflectiveTest
class NotMapSpreadTest extends DriverResolutionTest {
test_map() async {
@@ -28,6 +51,15 @@ var v = <int, int>{...?null};
''');
}
test_map_typeParameter_bound_map() async {
await assertNoErrorsInCode('''
void f<T extends Map<int, String>>(T a) {
var v = <int, String>{...a};
v;
}
''');
}
test_notMap_direct() async {
await assertErrorsInCode('''
var a = 0;
@@ -64,4 +96,15 @@ var v = <int, int>{if (1 > 0) ...a};
error(CompileTimeErrorCode.NOT_MAP_SPREAD, 44, 1),
]);
}
test_notMap_typeParameter_bound() async {
await assertErrorsInCode('''
void f<T extends num>(T a) {
var v = <int, int>{...a};
v;
}
''', [
error(CompileTimeErrorCode.NOT_MAP_SPREAD, 53, 1),
]);
}
}