Support for type formals in function LUB.

R=brianwilkerson@google.com, paulberry@google.com

Change-Id: I5576db2279810bf1e4fc4a73870f60ca50166ee7
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/106924
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Konstantin Shcheglov <scheglov@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 27dd52e..e1e8de8 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -1212,14 +1212,18 @@
       variables1.add(variable1);
       variables2.add(variable2);
       variablesFresh.add(variableFresh);
+
       DartType bound1 = p1.bound ?? DynamicTypeImpl.instance;
       DartType bound2 = p2.bound ?? DynamicTypeImpl.instance;
       bound1 = bound1.substitute2(variablesFresh, variables1);
       bound2 = bound2.substitute2(variablesFresh, variables2);
-      pFresh.bound = bound2;
       if (!relation(bound2, bound1, p2, p1)) {
         return null;
       }
+
+      if (!bound2.isDynamic) {
+        pFresh.bound = bound2;
+      }
     }
     return variablesFresh;
   }
diff --git a/pkg/analyzer/lib/src/generated/type_system.dart b/pkg/analyzer/lib/src/generated/type_system.dart
index 53d06e1..9a902c2 100644
--- a/pkg/analyzer/lib/src/generated/type_system.dart
+++ b/pkg/analyzer/lib/src/generated/type_system.dart
@@ -2342,8 +2342,30 @@
    *   Return a function type with those types.
    */
   DartType _functionLeastUpperBound(FunctionType f, FunctionType g) {
-    // TODO(rnystrom): Right now, this assumes f and g do not have any type
-    // parameters. Revisit that in the presence of generic methods.
+    var fTypeFormals = f.typeFormals;
+    var gTypeFormals = g.typeFormals;
+
+    // If F and G differ in their number of type parameters, then the
+    // least upper bound of F and G is Function.
+    if (fTypeFormals.length != gTypeFormals.length) {
+      return typeProvider.functionType;
+    }
+
+    // If F and G differ in bounds of their of type parameters, then the
+    // least upper bound of F and G is Function.
+    var freshTypeFormalTypes =
+        FunctionTypeImpl.relateTypeFormals(f, g, (t, s, _, __) => t == s);
+    if (freshTypeFormalTypes == null) {
+      return typeProvider.functionType;
+    }
+
+    var typeFormals = freshTypeFormalTypes
+        .map<TypeParameterElement>((t) => t.element)
+        .toList();
+
+    f = f.instantiate(freshTypeFormalTypes);
+    g = g.instantiate(freshTypeFormalTypes);
+
     List<DartType> fRequired = f.normalParameterTypes;
     List<DartType> gRequired = g.normalParameterTypes;
 
@@ -2394,7 +2416,14 @@
 
     // Calculate the LUB of the return type.
     DartType returnType = getLeastUpperBound(f.returnType, g.returnType);
-    return new FunctionElementImpl.synthetic(parameters, returnType).type;
+
+    if (AnalysisDriver.useSummary2) {
+      return FunctionTypeImpl.synthetic(returnType, typeFormals, parameters);
+    }
+
+    var element = FunctionElementImpl.synthetic(parameters, returnType);
+    element.typeParameters = typeFormals;
+    return element.type;
   }
 
   /**
diff --git a/pkg/analyzer/test/generated/type_system_test.dart b/pkg/analyzer/test/generated/type_system_test.dart
index 511ce30..d4792a5 100644
--- a/pkg/analyzer/test/generated/type_system_test.dart
+++ b/pkg/analyzer/test/generated/type_system_test.dart
@@ -414,17 +414,66 @@
    *
    * The return type defaults to `void` if omitted.
    */
-  FunctionType _functionType(List<DartType> required,
-      {List<DartType> optional,
-      Map<String, DartType> named,
-      DartType returns}) {
-    if (returns == null) {
-      returns = voidType;
+  FunctionType _functionType({
+    List<TypeParameterElement> typeFormals,
+    List<DartType> required,
+    List<DartType> optional,
+    Map<String, DartType> named,
+    DartType returns,
+  }) {
+    if (optional != null && named != null) {
+      throw ArgumentError(
+        'Cannot have both optional positional and named parameters.',
+      );
     }
 
-    return ElementFactory.functionElement8(required, returns,
-            optional: optional, named: named)
-        .type;
+    var parameters = <ParameterElement>[];
+    if (required != null) {
+      for (var i = 0; i < required.length; ++i) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            'r$i',
+            required[i],
+            ParameterKind.REQUIRED,
+          ),
+        );
+      }
+    }
+    if (optional != null) {
+      for (var i = 0; i < optional.length; ++i) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            'p$i',
+            optional[i],
+            ParameterKind.POSITIONAL,
+          ),
+        );
+      }
+    }
+    if (named != null) {
+      for (var namedEntry in named.entries) {
+        parameters.add(
+          ParameterElementImpl.synthetic(
+            namedEntry.key,
+            namedEntry.value,
+            ParameterKind.NAMED,
+          ),
+        );
+      }
+    }
+
+    return FunctionTypeImpl.synthetic(
+      returns ?? voidType,
+      typeFormals ?? const <TypeParameterElement>[],
+      parameters,
+    );
+  }
+
+  TypeParameterElementImpl _typeParameterElement(String name,
+      {DartType bound}) {
+    var element = TypeParameterElementImpl.synthetic(name);
+    element.bound = bound ?? typeProvider.objectType;
+    return element;
   }
 }
 
@@ -1205,92 +1254,170 @@
   }
 
   void test_functionsDifferentNamedTakeUnion() {
-    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
-    FunctionType type2 =
-        _functionType([], named: {'b': doubleType, 'c': stringType});
-    FunctionType expected =
-        _functionType([], named: {'a': intType, 'b': numType, 'c': stringType});
+    var type1 = _functionType(
+      named: {'a': intType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'b': doubleType, 'c': stringType},
+    );
+    var expected = _functionType(
+      named: {'a': intType, 'b': numType, 'c': stringType},
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsDifferentOptionalArityTakeMax() {
-    FunctionType type1 = _functionType([], optional: [intType]);
-    FunctionType type2 =
-        _functionType([], optional: [doubleType, stringType, objectType]);
-    FunctionType expected =
-        _functionType([], optional: [numType, stringType, objectType]);
+    var type1 = _functionType(
+      optional: [intType],
+    );
+    var type2 = _functionType(
+      required: [],
+      optional: [doubleType, stringType, objectType],
+    );
+    var expected = _functionType(
+      optional: [numType, stringType, objectType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsDifferentRequiredArityBecomeOptional() {
-    FunctionType type1 = _functionType([intType]);
-    FunctionType type2 = _functionType([intType, intType, intType]);
-    FunctionType expected =
-        _functionType([intType], optional: [intType, intType]);
+    var type1 = _functionType(
+      required: [intType],
+    );
+    var type2 = _functionType(
+      required: [intType, intType, intType],
+    );
+    var expected = _functionType(
+      required: [intType],
+      optional: [intType, intType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsFromDynamic() {
-    FunctionType type1 = _functionType([dynamicType]);
-    FunctionType type2 = _functionType([intType]);
-    FunctionType expected = _functionType([dynamicType]);
+    var type1 = _functionType(required: [dynamicType]);
+    var type2 = _functionType(required: [intType]);
+    var expected = _functionType(required: [dynamicType]);
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsGlbReturnType() {
-    FunctionType type1 = _functionType([], returns: intType);
-    FunctionType type2 = _functionType([], returns: numType);
-    FunctionType expected = _functionType([], returns: intType);
+    var type1 = _functionType(returns: intType);
+    var type2 = _functionType(returns: numType);
+    var expected = _functionType(returns: intType);
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubNamedParams() {
-    FunctionType type1 =
-        _functionType([], named: {'a': stringType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
-    FunctionType expected =
-        _functionType([], named: {'a': objectType, 'b': numType});
+    var type1 = _functionType(
+      named: {'a': stringType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'b': numType},
+    );
+    var expected = _functionType(
+      named: {'a': objectType, 'b': numType},
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubPositionalParams() {
-    FunctionType type1 = _functionType([], optional: [stringType, intType]);
-    FunctionType type2 = _functionType([], optional: [intType, numType]);
-    FunctionType expected = _functionType([], optional: [objectType, numType]);
+    var type1 = _functionType(
+      optional: [stringType, intType],
+    );
+    var type2 = _functionType(
+      optional: [intType, numType],
+    );
+    var expected = _functionType(
+      optional: [objectType, numType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsLubRequiredParams() {
-    FunctionType type1 = _functionType([stringType, intType, intType]);
-    FunctionType type2 = _functionType([intType, doubleType, numType]);
-    FunctionType expected = _functionType([objectType, numType, numType]);
+    var type1 = _functionType(
+      required: [stringType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType, doubleType, numType],
+    );
+    var expected = _functionType(
+      required: [objectType, numType, numType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsMixedOptionalAndRequiredBecomeOptional() {
-    FunctionType type1 = _functionType([intType, intType],
-        optional: [intType, intType, intType]);
-    FunctionType type2 = _functionType([intType], optional: [intType, intType]);
-    FunctionType expected = _functionType([intType],
-        optional: [intType, intType, intType, intType]);
+    var type1 = _functionType(
+      required: [intType, intType],
+      optional: [intType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType],
+      optional: [intType, intType],
+    );
+    var expected = _functionType(
+      required: [intType],
+      optional: [intType, intType, intType, intType],
+    );
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
   void test_functionsReturnBottomIfMixOptionalAndNamed() {
     // Dart doesn't allow a function to have both optional and named parameters,
     // so if we would have synthethized that, pick bottom instead.
-    FunctionType type1 = _functionType([intType], named: {'a': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType});
+    var type1 = _functionType(
+      required: [intType],
+      named: {'a': intType},
+    );
+    var type2 = _functionType(
+      required: [],
+      named: {'a': intType},
+    );
     _checkGreatestLowerBound(type1, type2, bottomType);
   }
 
-  void test_functionsSameType() {
-    FunctionType type1 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType type2 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType expected = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
+  void test_functionsSameType_withNamed() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    _checkGreatestLowerBound(type1, type2, expected);
+  }
+
+  void test_functionsSameType_withOptional() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
     _checkGreatestLowerBound(type1, type2, expected);
   }
 
@@ -1386,8 +1513,11 @@
       ElementFactory.typeParameterElement('T').type
     ];
     for (DartType type in types) {
-      _checkGreatestLowerBound(_functionType([], returns: voidType),
-          _functionType([], returns: type), _functionType([], returns: type));
+      _checkGreatestLowerBound(
+        _functionType(required: [], returns: voidType),
+        _functionType(required: [], returns: type),
+        _functionType(required: [], returns: type),
+      );
     }
   }
 }
@@ -1399,71 +1529,164 @@
     typeSystem = new Dart2TypeSystem(typeProvider);
   }
 
-  void test_functionsDifferentRequiredArity() {
-    FunctionType type1 = _functionType([intType, intType]);
-    FunctionType type2 = _functionType([intType, intType, intType]);
+  void test_differentRequiredArity() {
+    var type1 = _functionType(required: [intType, intType]);
+    var type2 = _functionType(required: [intType, intType, intType]);
     _checkLeastUpperBound(type1, type2, functionType);
   }
 
-  void test_functionsFuzzyArrows() {
-    FunctionType type1 = _functionType([dynamicType]);
-    FunctionType type2 = _functionType([intType]);
-    FunctionType expected = _functionType([intType]);
+  void test_fuzzyArrows() {
+    var type1 = _functionType(required: [dynamicType]);
+    var type2 = _functionType(required: [intType]);
+    var expected = _functionType(required: [intType]);
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbNamedParams() {
-    FunctionType type1 =
-        _functionType([], named: {'a': stringType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'b': numType});
-    FunctionType expected =
-        _functionType([], named: {'a': bottomType, 'b': intType});
+  void test_glbNamedParams() {
+    var type1 = _functionType(
+      named: {'a': stringType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'b': numType},
+    );
+    var expected = _functionType(
+      named: {'a': bottomType, 'b': intType},
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbPositionalParams() {
-    FunctionType type1 = _functionType([], optional: [stringType, intType]);
-    FunctionType type2 = _functionType([], optional: [intType, numType]);
-    FunctionType expected = _functionType([], optional: [bottomType, intType]);
+  void test_glbPositionalParams() {
+    var type1 = _functionType(
+      optional: [stringType, intType],
+    );
+    var type2 = _functionType(
+      optional: [intType, numType],
+    );
+    var expected = _functionType(
+      optional: [bottomType, intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsGlbRequiredParams() {
-    FunctionType type1 = _functionType([stringType, intType, intType]);
-    FunctionType type2 = _functionType([intType, doubleType, numType]);
-    FunctionType expected = _functionType([bottomType, bottomType, intType]);
+  void test_glbRequiredParams() {
+    var type1 = _functionType(
+      required: [stringType, intType, intType],
+    );
+    var type2 = _functionType(
+      required: [intType, doubleType, numType],
+    );
+    var expected = _functionType(
+      required: [bottomType, bottomType, intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsIgnoreExtraNamedParams() {
-    FunctionType type1 = _functionType([], named: {'a': intType, 'b': intType});
-    FunctionType type2 = _functionType([], named: {'a': intType, 'c': intType});
-    FunctionType expected = _functionType([], named: {'a': intType});
+  void test_ignoreExtraNamedParams() {
+    var type1 = _functionType(
+      named: {'a': intType, 'b': intType},
+    );
+    var type2 = _functionType(
+      named: {'a': intType, 'c': intType},
+    );
+    var expected = _functionType(
+      named: {'a': intType},
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsIgnoreExtraPositionalParams() {
-    FunctionType type1 =
-        _functionType([], optional: [intType, intType, stringType]);
-    FunctionType type2 = _functionType([], optional: [intType]);
-    FunctionType expected = _functionType([], optional: [intType]);
+  void test_ignoreExtraPositionalParams() {
+    var type1 = _functionType(
+      optional: [intType, intType, stringType],
+    );
+    var type2 = _functionType(
+      optional: [intType],
+    );
+    var expected = _functionType(
+      optional: [intType],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsLubReturnType() {
-    FunctionType type1 = _functionType([], returns: intType);
-    FunctionType type2 = _functionType([], returns: doubleType);
-    FunctionType expected = _functionType([], returns: numType);
+  void test_lubReturnType() {
+    var type1 = _functionType(returns: intType);
+    var type2 = _functionType(returns: doubleType);
+    var expected = _functionType(returns: numType);
     _checkLeastUpperBound(type1, type2, expected);
   }
 
-  void test_functionsSameType() {
-    FunctionType type1 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType type2 = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
-    FunctionType expected = _functionType([stringType, intType, numType],
-        optional: [doubleType], named: {'n': numType}, returns: intType);
+  void test_sameType_withNamed() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      named: {'n': numType},
+      returns: intType,
+    );
+
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_sameType_withOptional() {
+    var type1 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var type2 = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    var expected = _functionType(
+      required: [stringType, intType, numType],
+      optional: [doubleType],
+      returns: intType,
+    );
+
+    _checkLeastUpperBound(type1, type2, expected);
+  }
+
+  void test_typeFormals_differentBounds() {
+    var T1 = _typeParameterElement('T1', bound: intType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var T2 = _typeParameterElement('T2', bound: doubleType);
+    var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+    _checkLeastUpperBound(type1, type2, functionType);
+  }
+
+  void test_typeFormals_differentNumber() {
+    var T1 = _typeParameterElement('T1', bound: numType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var type2 = _functionType(returns: intType);
+
+    _checkLeastUpperBound(type1, type2, functionType);
+  }
+
+  void test_typeFormals_sameBounds() {
+    var T1 = _typeParameterElement('T1', bound: numType);
+    var type1 = _functionType(typeFormals: [T1], returns: T1.type);
+
+    var T2 = _typeParameterElement('T2', bound: numType);
+    var type2 = _functionType(typeFormals: [T2], returns: T2.type);
+
+    var TE = _typeParameterElement('T', bound: numType);
+    var expected = _functionType(typeFormals: [TE], returns: TE.type);
+
     _checkLeastUpperBound(type1, type2, expected);
   }
 }
@@ -1566,32 +1789,38 @@
   }
 
   void test_nestedFunctionsLubInnerParamTypes() {
-    FunctionType type1 = _functionType([
-      _functionType([stringType, intType, intType])
-    ]);
-    FunctionType type2 = _functionType([
-      _functionType([intType, doubleType, numType])
-    ]);
-    FunctionType expected = _functionType([
-      _functionType([objectType, numType, numType])
-    ]);
+    var type1 = _functionType(
+      required: [
+        _functionType(required: [stringType, intType, intType])
+      ],
+    );
+    var type2 = _functionType(
+      required: [
+        _functionType(required: [intType, doubleType, numType])
+      ],
+    );
+    var expected = _functionType(
+      required: [
+        _functionType(required: [objectType, numType, numType])
+      ],
+    );
     _checkLeastUpperBound(type1, type2, expected);
   }
 
   void test_nestedNestedFunctionsGlbInnermostParamTypes() {
-    FunctionType type1 = _functionType([
-      _functionType([
-        _functionType([stringType, intType, intType])
+    FunctionType type1 = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [stringType, intType, intType])
       ])
     ]);
-    FunctionType type2 = _functionType([
-      _functionType([
-        _functionType([intType, doubleType, numType])
+    FunctionType type2 = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [intType, doubleType, numType])
       ])
     ]);
-    FunctionType expected = _functionType([
-      _functionType([
-        _functionType([bottomType, bottomType, intType])
+    FunctionType expected = _functionType(required: [
+      _functionType(required: [
+        _functionType(required: [bottomType, bottomType, intType])
       ])
     ]);
     _checkLeastUpperBound(type1, type2, expected);
@@ -1840,9 +2069,10 @@
     ];
     for (DartType type in types) {
       _checkLeastUpperBound(
-          _functionType([], returns: voidType),
-          _functionType([], returns: type),
-          _functionType([], returns: voidType));
+        _functionType(returns: voidType),
+        _functionType(returns: type),
+        _functionType(returns: voidType),
+      );
     }
   }
 }
diff --git a/pkg/analyzer/test/src/summary/linker_test.dart b/pkg/analyzer/test/src/summary/linker_test.dart
index 3a24bb1..8d7a3e5 100644
--- a/pkg/analyzer/test/src/summary/linker_test.dart
+++ b/pkg/analyzer/test/src/summary/linker_test.dart
@@ -327,7 +327,7 @@
     ClassElementForLink_Class cls = library.getContainedName('C');
     expect(cls.fields, hasLength(1));
     var field = cls.fields[0];
-    expect(field.type.toString(), 'int Function(Never)');
+    expect(field.type.toString(), 'int Function<T>(T)');
   }
 
   void test_inferredType_instanceField_dynamic() {
diff --git a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
index 282c385..3ab3089 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_ast2_test.dart
@@ -136,14 +136,6 @@
     return elementFactory.libraryOfUri('${source.uri}');
   }
 
-  @override
-  @failingTest
-  test_syntheticFunctionType_genericClosure() async {
-    // TODO(scheglov) Bug in TypeSystem.getLeastUpperBound().
-    // LUB(<T>(T) → int, <T>(T) → int) gives `(T) → int`, note absence of `<T>`.
-    await super.test_syntheticFunctionType_genericClosure();
-  }
-
   void _addLibraryUnits(
     Source definingSource,
     CompilationUnit definingUnit,
diff --git a/pkg/analyzer/test/src/summary/resynthesize_common.dart b/pkg/analyzer/test/src/summary/resynthesize_common.dart
index f4c870d..151d00f 100644
--- a/pkg/analyzer/test/src/summary/resynthesize_common.dart
+++ b/pkg/analyzer/test/src/summary/resynthesize_common.dart
@@ -9431,7 +9431,7 @@
 bool f() => true;
 ''');
     checkElementText(library, r'''
-final int Function(Never) v;
+final int Function<T>(T) v;
 bool f() {}
 ''');
   }