[cfe] Check for cyclic typedefs at declare site instead of use site

Change-Id: I3738cd483b6436c630669edd6975b0fbb078d058
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/339941
Reviewed-by: Erik Ernst <eernst@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
Commit-Queue: Chloe Stefantsova <cstefantsova@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
index 0ed5d1d..b05b982 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_alias_builder.dart
@@ -255,9 +255,7 @@
       List<TypeBuilder>? unboundTypes,
       List<StructuralVariableBuilder>? unboundTypeVariables) {
     if (this == rootBuilder) {
-      // Cyclic type alias.
-      libraryBuilder.addProblem(templateCyclicTypedef.withArguments(this.name),
-          charOffset, noLength, fileUri);
+      // Cyclic type alias. The error is reported elsewhere.
       return null;
     }
     if (!currentBuilders.add(this)) {
@@ -333,14 +331,7 @@
         return _cachedUnaliasedDeclaration = this;
       }
       if (current == this) {
-        //if (builders.contains(current)) {
-        // Cyclic type alias.
-        currentAliasBuilder.libraryBuilder.addProblem(
-            templateCyclicTypedef.withArguments(this.name),
-            charOffset,
-            noLength,
-            fileUri);
-        // Ensure that it is not reported again.
+        // Cyclic type alias. The error is reported elsewhere.
         thisType = const InvalidType();
         return _cachedUnaliasedDeclaration = this;
       } else if (!builders.add(current)) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
index f08b35b..9e4bebb 100644
--- a/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/type_algorithms.dart
@@ -30,7 +30,6 @@
         templateBoundIssueViaCycleNonSimplicity,
         templateBoundIssueViaLoopNonSimplicity,
         templateBoundIssueViaRawTypeWithNonSimpleBounds,
-        templateCyclicTypedef,
         templateNonSimpleBoundViaReference,
         templateNonSimpleBoundViaVariable;
 
@@ -93,11 +92,8 @@
                 assert(!declaration.fromDill);
                 NominalVariableBuilder declarationTypeVariable =
                     declaration.typeVariables![i];
-                libraryBuilder.addProblem(
-                    templateCyclicTypedef.withArguments(declaration.name),
-                    declaration.charOffset,
-                    declaration.name.length,
-                    declaration.fileUri);
+                // Cyclic type alias. The error is reported elsewhere.
+
                 // Use [Variance.unrelated] for recovery.  The type with the
                 // cyclic dependency will be replaced with an [InvalidType]
                 // elsewhere.
@@ -1263,7 +1259,7 @@
     if (cycle.length == 1) {
       // Loop.
       issues.add(new NonSimplicityIssue(
-          cycle.single.typeVariable! as NominalVariableBuilder,
+          cycle.single.typeVariable!,
           templateBoundIssueViaLoopNonSimplicity
               .withArguments(cycle.single.type.declaration!.name),
           null));
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 9e9e396..23c0b07 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -9,17 +9,23 @@
 
 import '../builder/builder.dart';
 import '../builder/declaration_builders.dart';
+import '../builder/formal_parameter_builder.dart';
 import '../builder/library_builder.dart';
 import '../builder/member_builder.dart';
 import '../builder/metadata_builder.dart';
 import '../builder/name_iterator.dart';
+import '../builder/record_type_builder.dart';
 import '../builder/type_builder.dart';
+import '../dill/dill_class_builder.dart';
+import '../dill/dill_extension_type_declaration_builder.dart';
+import '../dill/dill_type_alias_builder.dart';
 import '../fasta_codes.dart'
-    show noLength, templateCyclicTypedef, templateTypeArgumentMismatch;
+    show templateCyclicTypedef, templateTypeArgumentMismatch;
 import '../kernel/body_builder_context.dart';
 import '../kernel/constructor_tearoff_lowering.dart';
 import '../kernel/expression_generator_helper.dart';
 import '../kernel/kernel_helper.dart';
+import '../kernel/type_builder_computer.dart';
 import '../problems.dart' show unhandled;
 import '../scope.dart';
 import '../util/helpers.dart';
@@ -85,16 +91,166 @@
 
   Typedef build() {
     buildThisType();
+    _checkCyclicTypedefDependency(type, this, {this});
+    if (typeVariables != null) {
+      for (TypeVariableBuilderBase typeVariable in typeVariables!) {
+        _checkCyclicTypedefDependency(typeVariable.bound, this, {this});
+      }
+    }
     return typedef;
   }
 
+  bool _checkCyclicTypedefDependency(
+      TypeBuilder? typeBuilder,
+      TypeAliasBuilder rootTypeAliasBuilder,
+      Set<TypeAliasBuilder> seenTypeAliasBuilders) {
+    switch (typeBuilder) {
+      case NamedTypeBuilder(
+          :TypeDeclarationBuilder? declaration,
+          typeArguments: List<TypeBuilder>? arguments
+        ):
+        if (declaration is TypeAliasBuilder) {
+          bool declarationSeenFirstTime =
+              seenTypeAliasBuilders.add(declaration);
+          if (declaration == rootTypeAliasBuilder) {
+            libraryBuilder.addProblem(
+                templateCyclicTypedef.withArguments(this.name),
+                rootTypeAliasBuilder.charOffset,
+                rootTypeAliasBuilder.name.length,
+                fileUri);
+            return true;
+          } else {
+            if (declarationSeenFirstTime) {
+              if (_checkCyclicTypedefDependency(declaration.type,
+                  rootTypeAliasBuilder, seenTypeAliasBuilders.toSet())) {
+                return true;
+              }
+            }
+          }
+        }
+        if (arguments != null) {
+          for (TypeBuilder typeArgument in arguments) {
+            if (_checkCyclicTypedefDependency(typeArgument,
+                rootTypeAliasBuilder, seenTypeAliasBuilders.toSet())) {
+              return true;
+            }
+          }
+        } else if (declaration != null && declaration.typeVariablesCount > 0) {
+          List<TypeVariableBuilderBase>? typeParameters;
+          List<TypeParameter>? typeParametersFromKernel;
+          bool isFromKernel = false;
+          switch (declaration) {
+            case ClassBuilder():
+              typeParameters = declaration.typeVariables;
+              if (declaration is DillClassBuilder) {
+                isFromKernel = true;
+                typeParametersFromKernel = declaration.cls.typeParameters;
+              }
+            case TypeAliasBuilder():
+              typeParameters = declaration.typeVariables;
+              if (declaration is DillTypeAliasBuilder) {
+                isFromKernel = true;
+                typeParametersFromKernel = declaration.typedef.typeParameters;
+              }
+            case ExtensionTypeDeclarationBuilder():
+              typeParameters = declaration.typeParameters;
+              if (declaration is DillExtensionTypeDeclarationBuilder) {
+                isFromKernel = true;
+                typeParametersFromKernel =
+                    declaration.extensionTypeDeclaration.typeParameters;
+              }
+            case BuiltinTypeDeclarationBuilder():
+            case InvalidTypeDeclarationBuilder():
+            case OmittedTypeDeclarationBuilder():
+            case ExtensionBuilder():
+            case TypeVariableBuilderBase():
+          }
+          if (typeParameters != null) {
+            TypeBuilderComputer? typeBuilderComputer;
+            for (int i = 0; i < typeParameters.length; i++) {
+              TypeVariableBuilderBase typeParameter = typeParameters[i];
+              if (!isFromKernel) {
+                if (_checkCyclicTypedefDependency(typeParameter.defaultType!,
+                    rootTypeAliasBuilder, seenTypeAliasBuilders.toSet())) {
+                  return true;
+                }
+              } else if (typeParametersFromKernel != null) {
+                assert(
+                    typeParameters.length == typeParametersFromKernel.length);
+                typeBuilderComputer ??=
+                    new TypeBuilderComputer(libraryBuilder.loader);
+                if (_checkCyclicTypedefDependency(
+                    typeParametersFromKernel[i]
+                        .defaultType
+                        .accept(typeBuilderComputer),
+                    rootTypeAliasBuilder,
+                    seenTypeAliasBuilders.toSet())) {
+                  return true;
+                }
+              }
+            }
+          }
+        }
+      case FunctionTypeBuilder(
+          :List<StructuralVariableBuilder>? typeVariables,
+          :List<ParameterBuilder>? formals,
+          :TypeBuilder returnType
+        ):
+        if (_checkCyclicTypedefDependency(
+            returnType, rootTypeAliasBuilder, seenTypeAliasBuilders.toSet())) {
+          return true;
+        }
+        if (formals != null) {
+          for (ParameterBuilder formal in formals) {
+            if (_checkCyclicTypedefDependency(formal.type, rootTypeAliasBuilder,
+                seenTypeAliasBuilders.toSet())) {
+              return true;
+            }
+          }
+        }
+        if (typeVariables != null) {
+          for (StructuralVariableBuilder typeVariable in typeVariables) {
+            TypeBuilder? bound = typeVariable.bound;
+            if (_checkCyclicTypedefDependency(
+                bound, rootTypeAliasBuilder, seenTypeAliasBuilders.toSet())) {
+              return true;
+            }
+          }
+        }
+      case RecordTypeBuilder(
+          :List<RecordTypeFieldBuilder>? positionalFields,
+          :List<RecordTypeFieldBuilder>? namedFields
+        ):
+        if (positionalFields != null) {
+          for (RecordTypeFieldBuilder field in positionalFields) {
+            if (_checkCyclicTypedefDependency(field.type, rootTypeAliasBuilder,
+                seenTypeAliasBuilders.toSet())) {
+              return true;
+            }
+          }
+        }
+        if (namedFields != null) {
+          for (RecordTypeFieldBuilder field in namedFields) {
+            if (_checkCyclicTypedefDependency(field.type, rootTypeAliasBuilder,
+                seenTypeAliasBuilders.toSet())) {
+              return true;
+            }
+          }
+        }
+      case OmittedTypeBuilder():
+      case FixedTypeBuilder():
+      case InvalidTypeBuilder():
+      case null:
+    }
+    return false;
+  }
+
   @override
   DartType buildThisType() {
     if (thisType != null) {
       if (identical(thisType, pendingTypeAliasMarker)) {
         thisType = cyclicTypeAliasMarker;
-        libraryBuilder.addProblem(templateCyclicTypedef.withArguments(name),
-            charOffset, noLength, fileUri);
+        // Cyclic type alias. The error is reported elsewhere.
         return const InvalidType();
       } else if (identical(thisType, cyclicTypeAliasMarker)) {
         return const InvalidType();
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.expect
index 1142c0b..fd1ffa7 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.transformed.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.transformed.expect
index 1142c0b..fd1ffa7 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.strong.transformed.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.expect
index 1142c0b..fd1ffa7 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.modular.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.modular.expect
index 1142c0b..fd1ffa7 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.modular.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.outline.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.outline.expect
index 3c10a63..8ca4c92 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.outline.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.transformed.expect b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.transformed.expect
index 1142c0b..fd1ffa7 100644
--- a/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/extension_types/cyclic_representation_type.dart.weak.transformed.expect
@@ -175,7 +175,7 @@
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:60:9: Error: The typedef 'Alias20' has a reference to itself.
 // typedef Alias20 = Alias20; /* Error */
-//         ^
+//         ^^^^^^^
 //
 // pkg/front_end/testcases/extension_types/cyclic_representation_type.dart:71:20: Error: An extension type can't depend on itself through its representation type.
 // extension type E23(Alias23 it) /* Error */ {}
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart b/pkg/front_end/testcases/general/cyclic_typedef.dart
new file mode 100644
index 0000000..6b2ccbc
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart
@@ -0,0 +1,14 @@
+// Copyright (c) 2023, 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.
+
+typedef F1<X> = List<G1<X>>;
+typedef G1<Y> = F1<Y>;
+
+typedef F2 = void Function<X extends F2>();
+
+typedef F3 = F3;
+
+typedef F4 = List<F4>;
+
+typedef F5<X extends F5<Never>> = Object;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.transformed.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.transformed.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.strong.transformed.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline.expect
new file mode 100644
index 0000000..c3ecc8b
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline.expect
@@ -0,0 +1,6 @@
+typedef F1<X> = List<G1<X>>;
+typedef G1<Y> = F1<Y>;
+typedef F2 = void Function<X extends F2>();
+typedef F3 = F3;
+typedef F4 = List<F4>;
+typedef F5<X extends F5<Never>> = Object;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..31e4b2e
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.textual_outline_modelled.expect
@@ -0,0 +1,6 @@
+typedef F1<X> = List<G1<X>>;
+typedef F2 = void Function<X extends F2>();
+typedef F3 = F3;
+typedef F4 = List<F4>;
+typedef F5<X extends F5<Never>> = Object;
+typedef G1<Y> = F1<Y>;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.modular.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.modular.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.modular.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.outline.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.outline.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.outline.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.transformed.expect b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.transformed.expect
new file mode 100644
index 0000000..4078fdb
--- /dev/null
+++ b/pkg/front_end/testcases/general/cyclic_typedef.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:8:28: Error: Generic type 'F2' can't be used without type arguments in the bounds of its own type variables.
+// Try providing type arguments to 'F2' here.
+// typedef F2 = void Function<X extends F2>();
+//                            ^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:5:9: Error: The typedef 'F1' has a reference to itself.
+// typedef F1<X> = List<G1<X>>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:6:9: Error: The typedef 'G1' has a reference to itself.
+// typedef G1<Y> = F1<Y>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:10:9: Error: The typedef 'F3' has a reference to itself.
+// typedef F3 = F3;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:12:9: Error: The typedef 'F4' has a reference to itself.
+// typedef F4 = List<F4>;
+//         ^^
+//
+// pkg/front_end/testcases/general/cyclic_typedef.dart:14:9: Error: The typedef 'F5' has a reference to itself.
+// typedef F5<X extends F5<Never>> = Object;
+//         ^^
+//
+import self as self;
+import "dart:core" as core;
+
+typedef F1<unrelated X extends core::Object? = dynamic> = invalid-type;
+typedef G1<unrelated Y extends core::Object? = dynamic> = invalid-type;
+typedef F2 = <X extends core::Object? = dynamic>() → void;
+typedef F3 = invalid-type;
+typedef F4 = invalid-type;
+typedef F5<unrelated X extends invalid-type> = invalid-type;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.expect
index 6d3bcfb..65e1844 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.transformed.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.transformed.expect
index 6d3bcfb..65e1844 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.strong.transformed.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.expect
index 6d3bcfb..65e1844 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.modular.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.modular.expect
index 6d3bcfb..65e1844 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.modular.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.outline.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.outline.expect
index 23d2f5a..63d1a8f 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.outline.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.transformed.expect b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.transformed.expect
index 6d3bcfb..65e1844 100644
--- a/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/general/three_typedefs_loop.dart.weak.transformed.expect
@@ -2,13 +2,17 @@
 //
 // Problems in library:
 //
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
+// typedef Foo<T> = void Function(Bar<T>);
+//         ^^^
+//
 // pkg/front_end/testcases/general/three_typedefs_loop.dart:8:9: Error: The typedef 'Bar' has a reference to itself.
 // typedef Bar<T> = void Function(Baz<T>);
 //         ^^^
 //
-// pkg/front_end/testcases/general/three_typedefs_loop.dart:7:9: Error: The typedef 'Foo' has a reference to itself.
-// typedef Foo<T> = void Function(Bar<T>);
-//         ^
+// pkg/front_end/testcases/general/three_typedefs_loop.dart:9:9: Error: The typedef 'Baz' has a reference to itself.
+// typedef Baz<T> = void Function(Foo<T>);
+//         ^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.expect
index 5d2a111..b2a778c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.transformed.expect
index 5d2a111..b2a778c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.strong.transformed.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.expect
index 5d2a111..b2a778c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.modular.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.modular.expect
index 5d2a111..b2a778c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.modular.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.outline.expect
index 107e90d..d51dab0 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.outline.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.transformed.expect
index 5d2a111..b2a778c 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart.weak.transformed.expect
@@ -26,7 +26,7 @@
 //
 // pkg/front_end/testcases/instantiate_to_bound/non_simple_class_parametrized_typedef_cycle2.dart:19:9: Error: The typedef 'Typedef3' has a reference to itself.
 // typedef Typedef3 = (void Function<Y3 extends Class3>(), int);
-//         ^
+//         ^^^^^^^^
 //
 import self as self;
 import "dart:core" as core;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
index 4400d31..018b99a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.expect
@@ -31,6 +31,13 @@
 static method main() → dynamic {}
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
index 4400d31..018b99a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.strong.transformed.expect
@@ -31,6 +31,13 @@
 static method main() → dynamic {}
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.expect
index 4400d31..018b99a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.expect
@@ -31,6 +31,13 @@
 static method main() → dynamic {}
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.modular.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.modular.expect
index 4400d31..018b99a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.modular.expect
@@ -31,6 +31,13 @@
 static method main() → dynamic {}
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.outline.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.outline.expect
index c0ec1f8..f2fb0f9 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.outline.expect
@@ -31,6 +31,13 @@
   ;
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.transformed.expect b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.transformed.expect
index 4400d31..018b99a 100644
--- a/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle.dart.weak.transformed.expect
@@ -31,6 +31,13 @@
 static method main() → dynamic {}
 
 library non_simple_many_libs_same_name_cycle_lib;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/instantiate_to_bound/non_simple_many_libs_same_name_cycle_lib.dart:18:9: Error: The typedef 'C' has a reference to itself.
+// typedef C<TypeY extends lib.C> = int;
+//         ^
+//
 import self as self2;
 import "dart:core" as core;
 import "non_simple_many_libs_same_name_cycle.dart" as self;
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
index 3444c42..c66039a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
index 3444c42..c66039a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.strong.transformed.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
index 3444c42..c66039a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.modular.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.modular.expect
index 3444c42..c66039a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.modular.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.modular.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
index dc3f69b..719ae30 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.outline.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
index 3444c42..c66039a 100644
--- a/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/rasta/malformed_function_type.dart.weak.transformed.expect
@@ -4,7 +4,7 @@
 //
 // pkg/front_end/testcases/rasta/malformed_function_type.dart:5:16: Error: The typedef 'Handle' has a reference to itself.
 // typedef Handle Handle(String command);
-//                ^
+//                ^^^^^^
 //
 import self as self;
 
diff --git a/tests/language/function/type_alias9_test.dart b/tests/language/function/type_alias9_test.dart
index 12ad3d6..f412bc8 100644
--- a/tests/language/function/type_alias9_test.dart
+++ b/tests/language/function/type_alias9_test.dart
@@ -10,6 +10,7 @@
 typedef void G(List<F> l);
 //           ^
 // [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'G' has a reference to itself.
 
 main() {
   F? foo(G? g) => g as F?;
diff --git a/tests/language/nonfunction_type_aliases/cyclic_bound_error_test.dart b/tests/language/nonfunction_type_aliases/cyclic_bound_error_test.dart
index 1d88c25b..e17e99c 100644
--- a/tests/language/nonfunction_type_aliases/cyclic_bound_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/cyclic_bound_error_test.dart
@@ -7,51 +7,51 @@
 // error, when the cycle occurs via the bound.
 
 typedef T1<X extends T1<Never>> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T1' has a reference to itself.
 
 // Note: when the cycle involves two typedefs, the CFE only reports an error for
 // one of them; that's ok.
 typedef T2<X extends T3> = List<X>;
-//      ^
-// [analyzer] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T2' has a reference to itself.
 
 typedef T3 = T2<Never>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 
 typedef T4<X extends List<T4<Never>>> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T4' has a reference to itself.
 
 typedef T5<X extends T5<Never> Function()> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T5' has a reference to itself.
 
 typedef T6<X extends void Function(T6<Never>)> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T6' has a reference to itself.
 
 // Note: not an error because T7 is the name of the parameter.
 typedef T7<X extends void Function(int T7)> = List<X>;
 
 typedef T8<X extends void Function([T8<Never>])> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T8' has a reference to itself.
 
 // Note: not an error because T9 is the name of the parameter.
 typedef T9<X extends void Function([int T9])> = List<X>;
 
 typedef T10<X extends void Function({T10<Never> x})> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T10' has a reference to itself.
 
 // Note: not an error because T11 is the name of the parameter.
 typedef T11<X extends void Function({int T11})> = List<X>;
@@ -59,6 +59,6 @@
 // Note: we have to use `void Function<...>() Function()` because a generic
 // function can't directly be used as a bound.
 typedef T12<X extends void Function<Y extends T12<Never>>() Function()> = List<X>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T12' has a reference to itself.
diff --git a/tests/language/nonfunction_type_aliases/cyclic_bound_unused_error_test.dart b/tests/language/nonfunction_type_aliases/cyclic_bound_unused_error_test.dart
index 4f1a188..36bd657c 100644
--- a/tests/language/nonfunction_type_aliases/cyclic_bound_unused_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/cyclic_bound_unused_error_test.dart
@@ -8,51 +8,51 @@
 // used in the expansion.
 
 typedef T1<X extends T1<Never>> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T1' has a reference to itself.
 
 // Note: when the cycle involves two typedefs, the CFE only reports an error for
 // one of them; that's ok.
 typedef T2<X extends T3> = int;
-//      ^
-// [analyzer] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T2' has a reference to itself.
 
 typedef T3 = T2<Never>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
 
 typedef T4<X extends List<T4<Never>>> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T4' has a reference to itself.
 
 typedef T5<X extends T5<Never> Function()> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T5' has a reference to itself.
 
 typedef T6<X extends void Function(T6<Never>)> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T6' has a reference to itself.
 
 // Note: not an error because T7 is the name of the parameter.
 typedef T7<X extends void Function(int T7)> = int;
 
 typedef T8<X extends void Function([T8<Never>])> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T8' has a reference to itself.
 
 // Note: not an error because T9 is the name of the parameter.
 typedef T9<X extends void Function([int T9])> = int;
 
 typedef T10<X extends void Function({T10<Never> x})> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T10' has a reference to itself.
 
 // Note: not an error because T11 is the name of the parameter.
 typedef T11<X extends void Function({int T11})> = int;
@@ -60,6 +60,6 @@
 // Note: we have to use `void Function<...>() Function()` because a generic
 // function can't directly be used as a bound.
 typedef T12<X extends void Function<Y extends T12<Never>>() Function()> = int;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T12' has a reference to itself.
diff --git a/tests/language/nonfunction_type_aliases/cyclic_expansion_error_test.dart b/tests/language/nonfunction_type_aliases/cyclic_expansion_error_test.dart
index 1839de7..8265153 100644
--- a/tests/language/nonfunction_type_aliases/cyclic_expansion_error_test.dart
+++ b/tests/language/nonfunction_type_aliases/cyclic_expansion_error_test.dart
@@ -7,56 +7,57 @@
 // error, when the cycle occurs via the expansion of the type.
 
 typedef T1 = List<T1>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T1' has a reference to itself.
 
 typedef T2 = List<T3>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T2' has a reference to itself.
 
 // Note: when the cycle involves two typedefs, the CFE only reports an error for
 // one of them; that's ok.
 typedef T3 = List<T2>;
-//      ^
-// [analyzer] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T3' has a reference to itself.
 
 typedef T4 = T4;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T4' has a reference to itself.
 
 typedef T5 = T5?;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T5' has a reference to itself.
 
 typedef T6 = List<T6 Function()>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T6' has a reference to itself.
 
 typedef T7 = List<void Function(T7)>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T7' has a reference to itself.
 
 // Note: not an error because T8 is the name of the parameter.
 typedef T8 = List<void Function(int T8)>;
 
 typedef T9 = List<void Function([T9])>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T9' has a reference to itself.
 
 // Note: not an error because T10 is the name of the parameter.
 typedef T10 = List<void Function([int T10])>;
 
 typedef T11 = List<void Function({T11 x})>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T11' has a reference to itself.
 
 // Note: not an error because T12 is the name of the parameter.
 typedef T12 = List<void Function({int T12})>;
@@ -64,6 +65,8 @@
 // Note: we have to use `void Function<...>() Function()` because a generic
 // function can't directly be used as a type argument.
 typedef T13 = List<void Function<X extends T13>() Function()>;
-//      ^
-// [analyzer] unspecified
-// [cfe] unspecified
+//      ^^^
+// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
+// [cfe] The typedef 'T13' has a reference to itself.
+//                                         ^^^
+// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND