| Index: pkg/analyzer/lib/src/generated/error_verifier.dart | 
| diff --git a/pkg/analyzer/lib/src/generated/error_verifier.dart b/pkg/analyzer/lib/src/generated/error_verifier.dart | 
| index 346da5a6c23f5e2fcfded2096a5c41cfc90fb89c..ffef5db56d9e8e3af77f73dad77cd3321a68c279 100644 | 
| --- a/pkg/analyzer/lib/src/generated/error_verifier.dart | 
| +++ b/pkg/analyzer/lib/src/generated/error_verifier.dart | 
| @@ -821,7 +821,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { | 
| StaticTypeWarningCode.INVOCATION_OF_NON_FUNCTION_EXPRESSION, | 
| functionExpression); | 
| } else if (expressionType is FunctionType) { | 
| -      _checkTypeArguments(expressionType.element, node.typeArguments); | 
| +      _checkTypeArguments(node); | 
| } | 
| _checkForImplicitDynamicInvoke(node); | 
| return super.visitFunctionExpressionInvocation(node); | 
| @@ -1032,8 +1032,7 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { | 
| } else { | 
| _checkForUnqualifiedReferenceToNonLocalStaticMember(methodName); | 
| } | 
| -    _checkTypeArguments( | 
| -        node.methodName.staticElement, node.typeArguments, target?.staticType); | 
| +    _checkTypeArguments(node); | 
| _checkForImplicitDynamicInvoke(node); | 
| return super.visitMethodInvocation(node); | 
| } | 
| @@ -6156,72 +6155,38 @@ class ErrorVerifier extends RecursiveAstVisitor<Object> { | 
| * | 
| * See [StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS]. | 
| */ | 
| -  void _checkTypeArguments(Element element, TypeArgumentList typeArguments, | 
| -      [DartType targetType]) { | 
| -    if (element == null || typeArguments == null) { | 
| -      return; | 
| -    } | 
| -    void reportError(TypeAnnotation argument, DartType argumentType, | 
| -        DartType parameterType) { | 
| -      _errorReporter.reportTypeErrorForNode( | 
| -          StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, | 
| -          argument, | 
| -          [argumentType, parameterType]); | 
| -    } | 
| - | 
| -    if (element is FunctionTypedElement) { | 
| -      _checkTypeArgumentsAgainstBounds( | 
| -          element.typeParameters, typeArguments, targetType, reportError); | 
| -    } else if (element is ClassElement) { | 
| -      _checkTypeArgumentsAgainstBounds( | 
| -          element.typeParameters, typeArguments, targetType, reportError); | 
| -    } else if (element is ParameterElement || element is LocalVariableElement) { | 
| -      // TODO(brianwilkerson) Implement this case | 
| -    } else { | 
| -      print('Unhandled element type: ${element.runtimeType}'); | 
| -    } | 
| -  } | 
| - | 
| -  void _checkTypeArgumentsAgainstBounds( | 
| -      List<TypeParameterElement> typeParameters, | 
| -      TypeArgumentList typeArgumentList, | 
| -      DartType targetType, | 
| -      void reportError(TypeAnnotation argument, DartType argumentType, | 
| -          DartType parameterType)) { | 
| -    NodeList<TypeAnnotation> typeArguments = typeArgumentList.arguments; | 
| -    int argumentsLength = typeArguments.length; | 
| -    int maxIndex = math.min(typeParameters.length, argumentsLength); | 
| - | 
| -    bool shouldSubstitute = | 
| -        argumentsLength != 0 && argumentsLength == typeParameters.length; | 
| -    List<DartType> argumentTypes = shouldSubstitute | 
| -        ? typeArguments.map((TypeAnnotation type) => type.type).toList() | 
| -        : null; | 
| -    List<DartType> parameterTypes = shouldSubstitute | 
| -        ? typeParameters | 
| -            .map((TypeParameterElement element) => element.type) | 
| -            .toList() | 
| -        : null; | 
| -    List<DartType> targetTypeParameterTypes = null; | 
| -    for (int i = 0; i < maxIndex; i++) { | 
| -      TypeAnnotation argument = typeArguments[i]; | 
| -      DartType argType = argument.type; | 
| -      DartType boundType = typeParameters[i].bound; | 
| -      if (argType != null && boundType != null) { | 
| -        if (targetType is ParameterizedType) { | 
| -          if (targetTypeParameterTypes == null) { | 
| -            targetTypeParameterTypes = targetType.typeParameters | 
| -                .map((TypeParameterElement element) => element.type) | 
| -                .toList(); | 
| -          } | 
| -          boundType = boundType.substitute2( | 
| -              targetType.typeArguments, targetTypeParameterTypes); | 
| -        } | 
| -        if (shouldSubstitute) { | 
| -          boundType = boundType.substitute2(argumentTypes, parameterTypes); | 
| -        } | 
| -        if (!_typeSystem.isSubtypeOf(argType, boundType)) { | 
| -          reportError(argument, argType, boundType); | 
| +  void _checkTypeArguments(InvocationExpression node) { | 
| +    NodeList<TypeAnnotation> typeArgumentList = node.typeArguments?.arguments; | 
| +    if (typeArgumentList == null) { | 
| +      return; | 
| +    } | 
| + | 
| +    var genericType = node.function.staticType; | 
| +    var instantiatedType = node.staticInvokeType; | 
| +    if (genericType is FunctionType && instantiatedType is FunctionType) { | 
| +      var fnTypeParams = | 
| +          TypeParameterTypeImpl.getTypes(genericType.typeFormals); | 
| +      var typeArgs = typeArgumentList.map((t) => t.type).toList(); | 
| + | 
| +      for (int i = 0, len = math.min(typeArgs.length, fnTypeParams.length); | 
| +          i < len; | 
| +          i++) { | 
| +        // Check the `extends` clause for the type parameter, if any. | 
| +        // | 
| +        // Also substitute to handle cases like this: | 
| +        // | 
| +        //     <TFrom, TTo extends TFrom> | 
| +        //     <TFrom, TTo extends Iterable<TFrom>> | 
| +        //     <T extends Clonable<T>> | 
| +        // | 
| +        DartType argType = typeArgs[i]; | 
| +        DartType bound = | 
| +            fnTypeParams[i].bound.substitute2(typeArgs, fnTypeParams); | 
| +        if (!_typeSystem.isSubtypeOf(argType, bound)) { | 
| +          _errorReporter.reportTypeErrorForNode( | 
| +              StaticTypeWarningCode.TYPE_ARGUMENT_NOT_MATCHING_BOUNDS, | 
| +              typeArgumentList[i], | 
| +              [argType, bound]); | 
| } | 
| } | 
| } | 
|  |