Extension types. Report TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND when via extension type.

Change-Id: I79d77e251fc4107e8d8496f9b4baea4b8a2b8bf0
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/319200
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
This commit is contained in:
Konstantin Shcheglov 2023-08-08 20:23:38 +00:00 committed by Commit Queue
parent c81711bdda
commit 5930cd6d55
3 changed files with 41 additions and 4 deletions

View file

@ -5,10 +5,23 @@
import 'package:analyzer/dart/element/element.dart';
import 'package:analyzer/dart/element/type.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/type.dart';
import 'package:analyzer/src/generated/utilities_dart.dart';
import 'package:collection/collection.dart';
import 'package:meta/meta_meta.dart';
extension DartTypeExtension on DartType {
/// If `this` is an [InterfaceType] that is an instantiation of an extension
/// type, returns its representation type erasure. Otherwise, returns self.
DartType get representationTypeErasureOrSelf {
final self = this;
if (self is InterfaceTypeImpl) {
return self.representationTypeErasure ?? self;
}
return self;
}
}
extension ElementAnnotationExtensions on ElementAnnotation {
static final Map<String, TargetKind> _targetKindsByName = {
for (final kind in TargetKind.values) kind.name: kind,

View file

@ -20,6 +20,7 @@ import 'package:analyzer/src/dart/ast/ast.dart';
import 'package:analyzer/src/dart/ast/extensions.dart';
import 'package:analyzer/src/dart/element/class_hierarchy.dart';
import 'package:analyzer/src/dart/element/element.dart';
import 'package:analyzer/src/dart/element/extensions.dart';
import 'package:analyzer/src/dart/element/inheritance_manager3.dart';
import 'package:analyzer/src/dart/element/non_covariant_type_parameter_position.dart';
import 'package:analyzer/src/dart/element/type.dart';
@ -4763,9 +4764,11 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
TypeParameter? current = parameter;
for (var step = 0; current != null; step++) {
var bound = current.bound;
if (bound is NamedType) {
current = elementToNode[bound.element];
final boundNode = current.bound;
if (boundNode is NamedType) {
var boundType = boundNode.typeOrThrow;
boundType = boundType.representationTypeErasureOrSelf;
current = elementToNode[boundType.element];
} else {
current = null;
}

View file

@ -17,7 +17,28 @@ main() {
@reflectiveTest
class TypeParameterSupertypeOfItsBoundTest extends PubPackageResolutionTest
with TypeParameterSupertypeOfItsBoundTestCases {}
with TypeParameterSupertypeOfItsBoundTestCases {
test_1of1_viaExtensionType() async {
await assertErrorsInCode(r'''
extension type A<T>(T it) {}
class B<U extends A<U>> {}
''', [
error(CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 38, 1),
]);
}
test_2of2_viaExtensionType() async {
await assertErrorsInCode(r'''
extension type A<T>(T it) {}
class B<T1 extends A<T2>, T2 extends T1> {}
''', [
error(CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 38, 2),
error(CompileTimeErrorCode.TYPE_PARAMETER_SUPERTYPE_OF_ITS_BOUND, 56, 2),
]);
}
}
mixin TypeParameterSupertypeOfItsBoundTestCases on PubPackageResolutionTest {
test_1of1() async {