[cfe] Don't block nnbd top merge on typedef types

The MergeVisitor was trying to merge FunctionType.typedefType in order
to merge function types, thus preventing nnbd top merge of two
compatible types that were just introduced through different typedefs
or function type syntax.

Change-Id: Icea75598168c86ed33314db22ebeec3e666c3675
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/184785
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
diff --git a/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_typedef.dart b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_typedef.dart
new file mode 100644
index 0000000..a3c4ea0
--- /dev/null
+++ b/pkg/_fe_analyzer_shared/test/inheritance/data/top_merge_typedef.dart
@@ -0,0 +1,46 @@
+// Copyright (c) 2021, the Dart project authors. Please see the AUTHORS file
+// for details. All rights reserved. Use of this source code is governed by a
+// BSD-style license that can be found in the LICENSE file.
+
+/*library: nnbd=true*/
+
+typedef Typedef1 = void Function();
+typedef Typedef2 = dynamic Function();
+
+/*class: A:A,Object*/
+abstract class A {
+  /*member: A.method1:void Function(void Function())*/
+  void method1(void Function() f);
+
+  /*member: A.method2:void Function(void Function())*/
+  void method2(Typedef1 f);
+
+  /*member: A.method3:void Function(void Function())*/
+  void method3(Typedef1 f);
+
+  /*member: A.method4:void Function(void Function())*/
+  void method4(void Function() f);
+}
+
+/*class: B:B,Object*/
+abstract class B {
+  /*member: B.method1:void Function(dynamic Function())*/
+  void method1(dynamic Function() f);
+
+  /*member: B.method2:void Function(dynamic Function())*/
+  void method2(Typedef2 f);
+
+  /*member: B.method3:void Function(dynamic Function())*/
+  void method3(dynamic Function() f);
+
+  /*member: B.method4:void Function(dynamic Function())*/
+  void method4(Typedef2 f);
+}
+
+/*class: C:A,B,C,Object*/
+abstract class C implements A, B {
+  /*member: C.method1:void Function(Object? Function())*/
+  /*member: C.method2:void Function(Object? Function())*/
+  /*member: C.method3:void Function(Object? Function())*/
+  /*member: C.method4:void Function(Object? Function())*/
+}
diff --git a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
index 2f22878..641352a 100644
--- a/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/combined_member_signature.dart
@@ -332,6 +332,10 @@
                   _coreTypes,
                   _combinedMemberSignatureType,
                   norm(_coreTypes, getMemberType(index)));
+              assert(
+                  _combinedMemberSignatureType != null,
+                  "No combined member signature found for "
+                  "${_mutualSubtypes.values.map((int i) => getMemberType(i))}");
             }
           }
           _neededNnbdTopMerge =
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index de66d20..f089d75 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -115,9 +115,10 @@
       newNamedParameters[i] = newNamedType;
     }
     TypedefType? newTypedefType;
-    if (a.typedefType != null) {
+    if (a.typedefType != null && b.typedefType != null) {
       newTypedefType = mergeTypes(a.typedefType, b.typedefType) as TypedefType?;
-      if (newTypedefType == null) return null;
+      // If the typedef couldn't be merged we just omit it from the resulting
+      // function type since the typedef type is only informational.
     }
 
     return new FunctionType(newPositionalParameters, newReturnType, nullability,