Resolve generic function default parameter values

Change-Id: I060ee8f61b8cb74482b92d4057e4183f1e4ca269
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/96701
Commit-Queue: Mike Fairhurst <mfairhurst@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Auto-Submit: Mike Fairhurst <mfairhurst@google.com>
diff --git a/pkg/analyzer/lib/src/dart/ast/ast.dart b/pkg/analyzer/lib/src/dart/ast/ast.dart
index e07a7e5..8dfa18b 100644
--- a/pkg/analyzer/lib/src/dart/ast/ast.dart
+++ b/pkg/analyzer/lib/src/dart/ast/ast.dart
@@ -3042,6 +3042,9 @@
   }
 
   @override
+  ParameterElement get declaredElement => _parameter.declaredElement;
+
+  @override
   Token get beginToken => _parameter.beginToken;
 
   @override
diff --git a/pkg/analyzer/lib/src/generated/resolver.dart b/pkg/analyzer/lib/src/generated/resolver.dart
index d685fda..523b409 100644
--- a/pkg/analyzer/lib/src/generated/resolver.dart
+++ b/pkg/analyzer/lib/src/generated/resolver.dart
@@ -4246,6 +4246,7 @@
         resolutionMap.elementDeclaredByFormalParameter(node.parameter)?.type);
     super.visitDefaultFormalParameter(node);
     ParameterElement element = node.declaredElement;
+
     if (element.initializer != null && node.defaultValue != null) {
       (element.initializer as FunctionElementImpl).returnType =
           node.defaultValue.staticType;
@@ -4513,9 +4514,6 @@
   }
 
   @override
-  void visitGenericFunctionType(GenericFunctionType node) {}
-
-  @override
   void visitGenericTypeAliasInFunctionScope(GenericTypeAlias node) {
     super.visitGenericTypeAliasInFunctionScope(node);
     safelyVisitComment(node.documentationComment);
diff --git a/pkg/analyzer/test/generated/compile_time_error_code.dart b/pkg/analyzer/test/generated/compile_time_error_code.dart
index 895f8e3..4a4f04d 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code.dart
@@ -1418,7 +1418,6 @@
     await computeAnalysisResult(source);
     assertErrors(source, [
       ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
-      StrongModeCode.INVALID_CAST_LITERAL_MAP
     ]);
     verify([source]);
   }
@@ -1430,7 +1429,6 @@
     await computeAnalysisResult(source);
     assertErrors(source, [
       ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
-      StrongModeCode.INVALID_CAST_LITERAL_MAP
     ]);
     verify([source]);
   }
diff --git a/pkg/analyzer/test/generated/compile_time_error_code_test.dart b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
index 62edcda..4a44fac 100644
--- a/pkg/analyzer/test/generated/compile_time_error_code_test.dart
+++ b/pkg/analyzer/test/generated/compile_time_error_code_test.dart
@@ -14,6 +14,8 @@
 main() {
   defineReflectiveSuite(() {
     defineReflectiveTests(CompileTimeErrorCodeTest);
+    defineReflectiveTests(CompileTimeErrorCodeTest_WithUIAsCode);
+    defineReflectiveTests(ConstSetElementTypeImplementsEqualsTest);
     defineReflectiveTests(ControlFlowCollectionsTest);
     defineReflectiveTests(InvalidTypeArgumentInConstSetTest);
     defineReflectiveTests(NonConstSetElementFromDeferredLibraryTest);
@@ -100,6 +102,141 @@
 }
 
 @reflectiveTest
+class CompileTimeErrorCodeTest_WithUIAsCode extends ResolverTestCase {
+  @override
+  List<String> get enabledExperiments =>
+      [EnableString.control_flow_collections, EnableString.spread_collections];
+
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_defaultValueInFunctionTypeAlias_new_named() async {
+    // This test used to fail with UI as code enabled. Test the fix here.
+    Source source = addSource('''
+typedef F = int Function({Map<String, String> m: const {}});
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
+    ]);
+    verify([source]);
+  }
+
+  test_defaultValueInFunctionTypeAlias_new_named_ambiguous() async {
+    // Strong checker asserts isSet || isMap. Prove that assertion holds.
+    Source source = addSource('''
+typedef F = int Function({Object m: const {1, 2: 3}});
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source, [
+      ParserErrorCode.DEFAULT_VALUE_IN_FUNCTION_TYPE,
+      CompileTimeErrorCode.AMBIGUOUS_SET_OR_MAP_LITERAL_BOTH,
+    ]);
+    verify([source]);
+  }
+}
+
+@reflectiveTest
+class ConstSetElementTypeImplementsEqualsTest extends ResolverTestCase {
+  @override
+  bool get enableNewAnalysisDriver => true;
+
+  test_constField() async {
+    Source source = addSource(r'''
+class A {
+  static const a = const A();
+  const A();
+  operator ==(other) => false;
+}
+main() {
+  const {A.a};
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_direct() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+main() {
+  const {const A()};
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_dynamic() async {
+    // Note: static type of B.a is "dynamic", but actual type of the const
+    // object is A.  We need to make sure we examine the actual type when
+    // deciding whether there is a problem with operator==.
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+class B {
+  static const a = const A();
+}
+main() {
+  const {B.a};
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_factory() async {
+    Source source = addSource(r'''
+class A { const factory A() = B; }
+
+class B implements A {
+  const B();
+
+  operator ==(o) => true;
+}
+
+main() {
+  var m = const {const A()};
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+
+  test_super() async {
+    Source source = addSource(r'''
+class A {
+  const A();
+  operator ==(other) => false;
+}
+class B extends A {
+  const B();
+}
+main() {
+  const {const B()};
+}
+''');
+    await computeAnalysisResult(source);
+    assertErrors(source,
+        [CompileTimeErrorCode.CONST_SET_ELEMENT_TYPE_IMPLEMENTS_EQUALS]);
+    verify([source]);
+  }
+}
+
+@reflectiveTest
 class ControlFlowCollectionsTest extends ResolverTestCase {
   @override
   List<String> get enabledExperiments =>
diff --git a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
index b47fb50..f5bb3d3 100644
--- a/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
+++ b/pkg/analyzer/test/src/dart/analysis/driver_resolution_test.dart
@@ -2114,7 +2114,6 @@
     var fTypeParameter = fType.normalParameterTypes[0] as TypeParameterType;
     expect(fTypeParameter.element, same(fTypeTypeParameter));
     var tRef = findNode.simple('T>');
-    assertType(tRef, null);
     var functionTypeNode = tRef.parent.parent.parent as GenericFunctionType;
     var functionType = functionTypeNode.type as FunctionType;
     assertElement(tRef, functionType.typeFormals[0]);