@@ -33,10 +33,22 @@ class TypeArgumentsVerifier {
33
33
_libraryElement.typeSystem as TypeSystemImpl ;
34
34
35
35
void checkFunctionExpressionInvocation (FunctionExpressionInvocation node) {
36
- _checkTypeArguments (node);
36
+ _checkTypeArguments (
37
+ node.typeArguments? .arguments,
38
+ node.function.staticType,
39
+ node.staticInvokeType,
40
+ );
37
41
_checkForImplicitDynamicInvoke (node);
38
42
}
39
43
44
+ void checkFunctionReference (FunctionReference node) {
45
+ _checkTypeArguments (
46
+ node.typeArguments? .arguments,
47
+ node.function.staticType,
48
+ node.staticType,
49
+ );
50
+ }
51
+
40
52
void checkListLiteral (ListLiteral node) {
41
53
var typeArguments = node.typeArguments;
42
54
if (typeArguments != null ) {
@@ -68,7 +80,11 @@ class TypeArgumentsVerifier {
68
80
}
69
81
70
82
void checkMethodInvocation (MethodInvocation node) {
71
- _checkTypeArguments (node);
83
+ _checkTypeArguments (
84
+ node.typeArguments? .arguments,
85
+ node.function.staticType,
86
+ node.staticInvokeType,
87
+ );
72
88
_checkForImplicitDynamicInvoke (node);
73
89
}
74
90
@@ -324,63 +340,65 @@ class TypeArgumentsVerifier {
324
340
}
325
341
}
326
342
327
- /// Verify that the given [typeArguments] are all within their bounds, as
328
- /// defined by the given [element] .
329
- void _checkTypeArguments (InvocationExpression node) {
330
- var typeArgumentList = node.typeArguments? .arguments;
343
+ /// Verify that each type argument in [typeArgumentList] is within its bounds,
344
+ /// as defined by [genericType] .
345
+ void _checkTypeArguments (
346
+ List <TypeAnnotation >? typeArgumentList,
347
+ DartType ? genericType,
348
+ DartType ? instantiatedType,
349
+ ) {
331
350
if (typeArgumentList == null ) {
332
351
return ;
333
352
}
334
353
335
- var genericType = node.function.staticType;
336
- var instantiatedType = node.staticInvokeType;
337
- if (genericType is FunctionType && instantiatedType is FunctionType ) {
338
- var fnTypeParams = genericType.typeFormals;
339
- var typeArgs = typeArgumentList.map ((t) => t.typeOrThrow).toList ();
340
-
341
- // If the amount mismatches, clean up the lists to be substitutable. The
342
- // mismatch in size is reported elsewhere, but we must successfully
343
- // perform substitution to validate bounds on mismatched lists.
344
- final providedLength = math.min (typeArgs.length, fnTypeParams.length);
345
- fnTypeParams = fnTypeParams.sublist (0 , providedLength);
346
- typeArgs = typeArgs.sublist (0 , providedLength);
347
-
348
- for (int i = 0 ; i < providedLength; i++ ) {
349
- // Check the `extends` clause for the type parameter, if any.
350
- //
351
- // Also substitute to handle cases like this:
352
- //
353
- // <TFrom, TTo extends TFrom>
354
- // <TFrom, TTo extends Iterable<TFrom>>
355
- // <T extends Cloneable<T>>
356
- //
357
- DartType argType = typeArgs[i];
358
-
359
- if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
360
- if (! _libraryElement.featureSet.isEnabled (Feature .generic_metadata)) {
361
- _errorReporter.reportErrorForNode (
362
- CompileTimeErrorCode
363
- .GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT ,
364
- typeArgumentList[i],
365
- );
366
- continue ;
367
- }
368
- }
354
+ if (genericType is ! FunctionType || instantiatedType is ! FunctionType ) {
355
+ return ;
356
+ }
369
357
370
- var fnTypeParam = fnTypeParams[i];
371
- var rawBound = fnTypeParam.bound;
372
- if (rawBound == null ) {
358
+ var fnTypeParams = genericType.typeFormals;
359
+ var typeArgs = typeArgumentList.map ((t) => t.typeOrThrow).toList ();
360
+
361
+ // If the amount mismatches, clean up the lists to be substitutable. The
362
+ // mismatch in size is reported elsewhere, but we must successfully
363
+ // perform substitution to validate bounds on mismatched lists.
364
+ var providedLength = math.min (typeArgs.length, fnTypeParams.length);
365
+ fnTypeParams = fnTypeParams.sublist (0 , providedLength);
366
+ typeArgs = typeArgs.sublist (0 , providedLength);
367
+
368
+ for (int i = 0 ; i < providedLength; i++ ) {
369
+ // Check the `extends` clause for the type parameter, if any.
370
+ //
371
+ // Also substitute to handle cases like this:
372
+ //
373
+ // <TFrom, TTo extends TFrom>
374
+ // <TFrom, TTo extends Iterable<TFrom>>
375
+ // <T extends Cloneable<T>>
376
+ //
377
+ DartType argType = typeArgs[i];
378
+
379
+ if (argType is FunctionType && argType.typeFormals.isNotEmpty) {
380
+ if (! _libraryElement.featureSet.isEnabled (Feature .generic_metadata)) {
381
+ _errorReporter.reportErrorForNode (
382
+ CompileTimeErrorCode .GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT ,
383
+ typeArgumentList[i],
384
+ );
373
385
continue ;
374
386
}
387
+ }
375
388
376
- var substitution = Substitution .fromPairs (fnTypeParams, typeArgs);
377
- var bound = substitution.substituteType (rawBound);
378
- if (! _typeSystem.isSubtypeOf (argType, bound)) {
379
- _errorReporter.reportErrorForNode (
380
- CompileTimeErrorCode .TYPE_ARGUMENT_NOT_MATCHING_BOUNDS ,
381
- typeArgumentList[i],
382
- [argType, fnTypeParam.name, bound]);
383
- }
389
+ var fnTypeParam = fnTypeParams[i];
390
+ var rawBound = fnTypeParam.bound;
391
+ if (rawBound == null ) {
392
+ continue ;
393
+ }
394
+
395
+ var substitution = Substitution .fromPairs (fnTypeParams, typeArgs);
396
+ var bound = substitution.substituteType (rawBound);
397
+ if (! _typeSystem.isSubtypeOf (argType, bound)) {
398
+ _errorReporter.reportErrorForNode (
399
+ CompileTimeErrorCode .TYPE_ARGUMENT_NOT_MATCHING_BOUNDS ,
400
+ typeArgumentList[i],
401
+ [argType, fnTypeParam.name, bound]);
384
402
}
385
403
}
386
404
}
0 commit comments