Skip to content

Commit 778c236

Browse files
scheglovcommit-bot@chromium.org
authored andcommitted
Issue 45579. Report WRONG_NUMBER_OF_TYPE_ARGUMENTS and TYPE_ARGUMENT_NOT_MATCHING_BOUNDS.
Bug: #45579 Change-Id: I757f4d782895fb1a9c89d8238a7929e12d6a6eed Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/194000 Reviewed-by: Brian Wilkerson <[email protected]> Commit-Queue: Konstantin Shcheglov <[email protected]>
1 parent 2cfd6e4 commit 778c236

File tree

3 files changed

+167
-0
lines changed

3 files changed

+167
-0
lines changed

pkg/analyzer/lib/src/dart/resolver/annotation_resolver.dart

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ import 'package:analyzer/src/dart/constant/utilities.dart';
1414
import 'package:analyzer/src/dart/element/element.dart';
1515
import 'package:analyzer/src/dart/element/member.dart';
1616
import 'package:analyzer/src/dart/element/type.dart';
17+
import 'package:analyzer/src/dart/element/type_algebra.dart';
1718
import 'package:analyzer/src/dart/resolver/invocation_inference_helper.dart';
1819
import 'package:analyzer/src/error/codes.dart';
1920
import 'package:analyzer/src/generated/resolver.dart';
@@ -65,6 +66,7 @@ class AnnotationResolver {
6566

6667
_constructorInvocation(
6768
node,
69+
classElement.name,
6870
constructorName,
6971
classElement.typeParameters,
7072
constructorElement,
@@ -113,6 +115,7 @@ class AnnotationResolver {
113115

114116
void _constructorInvocation(
115117
AnnotationImpl node,
118+
String typeDisplayName,
116119
SimpleIdentifierImpl? constructorName,
117120
List<TypeParameterElement> typeParameters,
118121
ConstructorElement? constructorElement,
@@ -136,6 +139,18 @@ class AnnotationResolver {
136139

137140
// If no type parameters, the elements are correct.
138141
if (typeParameters.isEmpty) {
142+
var typeArgumentList = node.typeArguments;
143+
if (typeArgumentList != null) {
144+
_errorReporter.reportErrorForNode(
145+
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
146+
typeArgumentList,
147+
[
148+
typeDisplayName,
149+
typeParameters.length,
150+
typeArgumentList.arguments.length,
151+
],
152+
);
153+
}
139154
_resolveConstructorInvocationArguments(node);
140155
InferenceContext.setType(argumentList, constructorElement.type);
141156
_resolver.visitArgumentList(argumentList,
@@ -174,7 +189,35 @@ class AnnotationResolver {
174189
typeArguments = typeArgumentList.arguments
175190
.map((element) => element.typeOrThrow)
176191
.toList();
192+
var substitution = Substitution.fromPairs(
193+
typeParameters,
194+
typeArguments,
195+
);
196+
for (var i = 0; i < typeParameters.length; i++) {
197+
var typeParameter = typeParameters[i];
198+
var bound = typeParameter.bound;
199+
if (bound != null) {
200+
bound = substitution.substituteType(bound);
201+
var typeArgument = typeArguments[i];
202+
if (!_resolver.typeSystem.isSubtypeOf(typeArgument, bound)) {
203+
_errorReporter.reportErrorForNode(
204+
CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS,
205+
typeArgumentList.arguments[i],
206+
[typeArgument, typeParameter.name, bound],
207+
);
208+
}
209+
}
210+
}
177211
} else {
212+
_errorReporter.reportErrorForNode(
213+
CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS,
214+
typeArgumentList,
215+
[
216+
typeDisplayName,
217+
typeParameters.length,
218+
typeArgumentList.arguments.length,
219+
],
220+
);
178221
typeArguments = List.filled(
179222
typeParameters.length,
180223
DynamicTypeImpl.instance,
@@ -458,6 +501,7 @@ class AnnotationResolver {
458501

459502
_constructorInvocation(
460503
node,
504+
typeAliasElement.name,
461505
constructorName,
462506
typeAliasElement.typeParameters,
463507
constructorElement,

pkg/analyzer/test/src/diagnostics/type_argument_not_matching_bounds_test.dart

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -471,6 +471,45 @@ void f(CB<F2> a) {}
471471
''');
472472
}
473473

474+
test_metadata_matching() async {
475+
await assertNoErrorsInCode(r'''
476+
class A<T extends num> {
477+
const A();
478+
}
479+
480+
@A<int>()
481+
void f() {}
482+
''');
483+
}
484+
485+
test_metadata_notMatching() async {
486+
await assertErrorsInCode(r'''
487+
class A<T extends num> {
488+
const A();
489+
}
490+
491+
@A<String>()
492+
void f() {}
493+
''', [
494+
error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 44, 6),
495+
]);
496+
}
497+
498+
test_metadata_notMatching_viaTypeAlias() async {
499+
await assertErrorsInCode(r'''
500+
class A<T> {
501+
const A();
502+
}
503+
504+
typedef B<T extends num> = A<T>;
505+
506+
@B<String>()
507+
void f() {}
508+
''', [
509+
error(CompileTimeErrorCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, 66, 6),
510+
]);
511+
}
512+
474513
test_methodInvocation_genericFunctionTypeArgument_match() async {
475514
await assertNoErrorsInCode(r'''
476515
typedef F = void Function<T extends num>();

pkg/analyzer/test/src/diagnostics/wrong_number_of_type_arguments_test.dart

Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,90 @@ dynamic<int> v;
9393
]);
9494
}
9595

96+
test_metadata_1of0() async {
97+
await assertErrorsInCode(r'''
98+
class A {
99+
const A();
100+
}
101+
102+
@A<int>()
103+
void f() {}
104+
''', [
105+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 28, 5),
106+
]);
107+
}
108+
109+
test_metadata_1of0_viaTypeAlias() async {
110+
await assertErrorsInCode(r'''
111+
class A {
112+
const A();
113+
}
114+
115+
typedef B = A;
116+
117+
@B<int>()
118+
void f() {}
119+
''', [
120+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 44, 5),
121+
]);
122+
}
123+
124+
test_metadata_1of2() async {
125+
await assertErrorsInCode(r'''
126+
class A<T, U> {
127+
const A();
128+
}
129+
130+
@A<int>()
131+
void f() {}
132+
''', [
133+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 34, 5),
134+
]);
135+
}
136+
137+
test_metadata_1of2_viaTypeAlias() async {
138+
await assertErrorsInCode(r'''
139+
class A {
140+
const A();
141+
}
142+
143+
typedef B<T, U> = A;
144+
145+
@B<int>()
146+
void f() {}
147+
''', [
148+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 50, 5),
149+
]);
150+
}
151+
152+
test_metadata_2of1() async {
153+
await assertErrorsInCode(r'''
154+
class A<T> {
155+
const A();
156+
}
157+
158+
@A<int, String>()
159+
void f() {}
160+
''', [
161+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 31, 13),
162+
]);
163+
}
164+
165+
test_metadata_2of1_viaTypeAlias() async {
166+
await assertErrorsInCode(r'''
167+
class A {
168+
const A();
169+
}
170+
171+
typedef B<T> = A;
172+
173+
@B<int, String>()
174+
void f() {}
175+
''', [
176+
error(CompileTimeErrorCode.WRONG_NUMBER_OF_TYPE_ARGUMENTS, 47, 13),
177+
]);
178+
}
179+
96180
test_new_nonGeneric() async {
97181
await assertErrorsInCode('''
98182
class C {}

0 commit comments

Comments
 (0)