[cfe] Move unboundNominal/StructuralVariables to SourceCompilationUnit

Change-Id: Id40e0777d078c55dbdc17fc3f1117ba8ebd0342e
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/375001
Reviewed-by: Jens Johansen <jensj@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/builder/fixed_type_builder.dart b/pkg/front_end/lib/src/builder/fixed_type_builder.dart
index 4882626..73ac9fe 100644
--- a/pkg/front_end/lib/src/builder/fixed_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/fixed_type_builder.dart
@@ -6,6 +6,7 @@
 import 'package:kernel/class_hierarchy.dart';
 
 import '../base/problems.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import 'library_builder.dart';
 import 'nullability_builder.dart';
@@ -24,7 +25,7 @@
   // Coverage-ignore(suite): Not run.
   TypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     return this;
   }
diff --git a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
index a2a4f52..cf3f455 100644
--- a/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
+++ b/pkg/front_end/lib/src/builder/formal_parameter_builder.dart
@@ -51,7 +51,7 @@
 
   ParameterBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration);
 }
 
@@ -189,10 +189,10 @@
   @override
   ParameterBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     return new FunctionTypeParameterBuilder(
-        kind, type.clone(newTypes, contextLibrary, contextDeclaration), name);
+        kind, type.clone(newTypes, builderFactory, contextDeclaration), name);
   }
 
   FormalParameterBuilder forPrimaryConstructor(BuilderFactory builderFactory) {
@@ -323,10 +323,10 @@
   // Coverage-ignore(suite): Not run.
   ParameterBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     return new FunctionTypeParameterBuilder(
-        kind, type.clone(newTypes, contextLibrary, contextDeclaration), name);
+        kind, type.clone(newTypes, builderFactory, contextDeclaration), name);
   }
 
   @override
diff --git a/pkg/front_end/lib/src/builder/function_type_builder.dart b/pkg/front_end/lib/src/builder/function_type_builder.dart
index 6abd7e3..4ea55b0 100644
--- a/pkg/front_end/lib/src/builder/function_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/function_type_builder.dart
@@ -11,6 +11,7 @@
 
 import '../codes/cfe_codes.dart' show messageSupertypeIsFunction, noLength;
 import '../kernel/implicit_field_type.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import 'declaration_builders.dart';
 import 'formal_parameter_builder.dart';
@@ -204,11 +205,11 @@
   @override
   FunctionTypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     List<StructuralVariableBuilder>? clonedTypeVariables;
     if (typeVariables != null) {
-      clonedTypeVariables = contextLibrary.copyStructuralVariables(
+      clonedTypeVariables = builderFactory.copyStructuralVariables(
           typeVariables!, contextDeclaration,
           kind: TypeVariableKind.function);
     }
@@ -217,11 +218,11 @@
       clonedFormals =
           new List<ParameterBuilder>.generate(formals!.length, (int i) {
         ParameterBuilder formal = formals![i];
-        return formal.clone(newTypes, contextLibrary, contextDeclaration);
+        return formal.clone(newTypes, builderFactory, contextDeclaration);
       }, growable: false);
     }
     return new FunctionTypeBuilderImpl(
-        returnType.clone(newTypes, contextLibrary, contextDeclaration),
+        returnType.clone(newTypes, builderFactory, contextDeclaration),
         clonedTypeVariables,
         clonedFormals,
         nullabilityBuilder,
diff --git a/pkg/front_end/lib/src/builder/invalid_type_builder.dart b/pkg/front_end/lib/src/builder/invalid_type_builder.dart
index 11cd26a..b0d116a 100644
--- a/pkg/front_end/lib/src/builder/invalid_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/invalid_type_builder.dart
@@ -5,6 +5,7 @@
 import 'package:kernel/ast.dart';
 import 'package:kernel/class_hierarchy.dart';
 
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import 'library_builder.dart';
 import 'nullability_builder.dart';
@@ -51,7 +52,7 @@
   // Coverage-ignore(suite): Not run.
   TypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     return this;
   }
diff --git a/pkg/front_end/lib/src/builder/library_builder.dart b/pkg/front_end/lib/src/builder/library_builder.dart
index da44a4b..b060c4b 100644
--- a/pkg/front_end/lib/src/builder/library_builder.dart
+++ b/pkg/front_end/lib/src/builder/library_builder.dart
@@ -184,10 +184,6 @@
 
   List<MetadataBuilder>? get metadata;
 
-  List<NominalVariableBuilder> get unboundNominalVariables;
-
-  List<StructuralVariableBuilder> get unboundStructuralVariables;
-
   void collectInferableTypes(List<InferableType> inferableTypes);
 
   void takeMixinApplications(
@@ -261,6 +257,17 @@
 
   void computeShowHideElements(ClassMembersBuilder membersBuilder);
 
+  /// Adds all unbound nominal variables to [nominalVariables] and unbound
+  /// structural variables to [structuralVariables], mapping them to
+  /// [libraryBuilder].
+  ///
+  /// This is used to compute the bounds of type variable while taking the
+  /// bound dependencies, which might span multiple libraries, into account.
+  void collectUnboundTypeVariables(
+      SourceLibraryBuilder libraryBuilder,
+      Map<NominalVariableBuilder, SourceLibraryBuilder> nominalVariables,
+      Map<StructuralVariableBuilder, SourceLibraryBuilder> structuralVariables);
+
   // TODO(johnniwinther): Remove this.
   Builder addBuilder(String name, Builder declaration, int charOffset);
 }
diff --git a/pkg/front_end/lib/src/builder/named_type_builder.dart b/pkg/front_end/lib/src/builder/named_type_builder.dart
index 4461f4f..38dbc6b 100644
--- a/pkg/front_end/lib/src/builder/named_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/named_type_builder.dart
@@ -36,6 +36,7 @@
 import '../base/scope.dart';
 import '../base/uris.dart';
 import '../kernel/implicit_field_type.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import '../util/helpers.dart';
 import 'builder.dart';
@@ -660,14 +661,14 @@
   @override
   NamedTypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     List<TypeBuilder>? clonedArguments;
     if (typeArguments != null) {
       clonedArguments =
           new List<TypeBuilder>.generate(typeArguments!.length, (int i) {
         return typeArguments![i]
-            .clone(newTypes, contextLibrary, contextDeclaration);
+            .clone(newTypes, builderFactory, contextDeclaration);
       }, growable: false);
     }
     NamedTypeBuilderImpl newType = new NamedTypeBuilderImpl(
diff --git a/pkg/front_end/lib/src/builder/omitted_type_builder.dart b/pkg/front_end/lib/src/builder/omitted_type_builder.dart
index c5ca674..6366054 100644
--- a/pkg/front_end/lib/src/builder/omitted_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/omitted_type_builder.dart
@@ -6,6 +6,7 @@
 import 'package:kernel/class_hierarchy.dart';
 
 import '../kernel/implicit_field_type.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import 'inferable_type_builder.dart';
 import 'library_builder.dart';
@@ -32,7 +33,7 @@
   @override
   TypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     return this;
   }
diff --git a/pkg/front_end/lib/src/builder/record_type_builder.dart b/pkg/front_end/lib/src/builder/record_type_builder.dart
index 6cc1086..1508d07 100644
--- a/pkg/front_end/lib/src/builder/record_type_builder.dart
+++ b/pkg/front_end/lib/src/builder/record_type_builder.dart
@@ -17,6 +17,7 @@
         templateDuplicatedRecordTypeFieldName,
         templateDuplicatedRecordTypeFieldNameContext;
 import '../kernel/implicit_field_type.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import '../util/helpers.dart';
 import 'inferable_type_builder.dart';
@@ -288,14 +289,14 @@
   @override
   RecordTypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     List<RecordTypeFieldBuilder>? clonedPositional;
     if (positionalFields != null) {
       clonedPositional = new List<RecordTypeFieldBuilder>.generate(
           positionalFields!.length, (int i) {
         RecordTypeFieldBuilder entry = positionalFields![i];
-        return entry.clone(newTypes, contextLibrary, contextDeclaration);
+        return entry.clone(newTypes, builderFactory, contextDeclaration);
       }, growable: false);
     }
     List<RecordTypeFieldBuilder>? clonedNamed;
@@ -304,7 +305,7 @@
       clonedNamed = new List<RecordTypeFieldBuilder>.generate(
           namedFields!.length, (int i) {
         RecordTypeFieldBuilder entry = namedFields![i];
-        return entry.clone(newTypes, contextLibrary, contextDeclaration);
+        return entry.clone(newTypes, builderFactory, contextDeclaration);
       }, growable: false);
     }
     return new RecordTypeBuilderImpl(
@@ -402,13 +403,13 @@
 
   RecordTypeFieldBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration) {
     // TODO(cstefantsova):  It's not clear how [metadata] is used currently,
     // and how it should be cloned.  Consider cloning it instead of reusing it.
     return new RecordTypeFieldBuilder(
         metadata,
-        type.clone(newTypes, contextLibrary, contextDeclaration),
+        type.clone(newTypes, builderFactory, contextDeclaration),
         name,
         charOffset,
         isWildcard: isWildcard);
diff --git a/pkg/front_end/lib/src/builder/type_builder.dart b/pkg/front_end/lib/src/builder/type_builder.dart
index 6929f32..d54fc70 100644
--- a/pkg/front_end/lib/src/builder/type_builder.dart
+++ b/pkg/front_end/lib/src/builder/type_builder.dart
@@ -10,6 +10,7 @@
 import '../base/messages.dart';
 import '../base/scope.dart';
 import '../kernel/type_algorithms.dart';
+import '../source/builder_factory.dart';
 import '../source/source_library_builder.dart';
 import 'declaration_builders.dart';
 import 'formal_parameter_builder.dart';
@@ -377,7 +378,7 @@
   /// resolved later.
   TypeBuilder clone(
       List<NamedTypeBuilder> newTypes,
-      SourceLibraryBuilder contextLibrary,
+      BuilderFactory builderFactory,
       TypeParameterScopeBuilder contextDeclaration);
 
   String get fullNameForErrors => "${printOn(new StringBuffer())}";
diff --git a/pkg/front_end/lib/src/source/builder_factory.dart b/pkg/front_end/lib/src/source/builder_factory.dart
index 1a05e4c..3b39e21 100644
--- a/pkg/front_end/lib/src/source/builder_factory.dart
+++ b/pkg/front_end/lib/src/source/builder_factory.dart
@@ -323,6 +323,14 @@
       TypeParameterScopeBuilder declaration,
       {required TypeVariableKind kind});
 
+  List<StructuralVariableBuilder> copyStructuralVariables(
+      List<StructuralVariableBuilder> original,
+      TypeParameterScopeBuilder declaration,
+      {required TypeVariableKind kind});
+
+  void registerUnboundStructuralVariables(
+      List<StructuralVariableBuilder> variableBuilders);
+
   Builder addBuilder(String name, Builder declaration, int charOffset,
       {Reference? getterReference, Reference? setterReference});
 }
diff --git a/pkg/front_end/lib/src/source/outline_builder.dart b/pkg/front_end/lib/src/source/outline_builder.dart
index 40e6b2d..3b1629c 100644
--- a/pkg/front_end/lib/src/source/outline_builder.dart
+++ b/pkg/front_end/lib/src/source/outline_builder.dart
@@ -2366,8 +2366,8 @@
           for (NamedTypeBuilder unboundType in unboundTypes) {
             declaration.registerUnresolvedNamedType(unboundType);
           }
-          _compilationUnit.unboundStructuralVariables
-              .addAll(unboundTypeVariables);
+          _builderFactory
+              .registerUnboundStructuralVariables(unboundTypeVariables);
         }
         synthesizedFormals.add(new FormalParameterBuilder(
             FormalParameterKind.requiredPositional,
diff --git a/pkg/front_end/lib/src/source/source_compilation_unit.dart b/pkg/front_end/lib/src/source/source_compilation_unit.dart
index 34921fa..097393e 100644
--- a/pkg/front_end/lib/src/source/source_compilation_unit.dart
+++ b/pkg/front_end/lib/src/source/source_compilation_unit.dart
@@ -75,6 +75,12 @@
   @override
   final IndexedLibrary? indexedLibrary;
 
+  final List<NominalVariableBuilder> _unboundNominalVariables =
+      <NominalVariableBuilder>[];
+
+  final List<StructuralVariableBuilder> _unboundStructuralVariables =
+      <StructuralVariableBuilder>[];
+
   SourceCompilationUnitImpl(
       this._sourceLibraryBuilder, this._libraryTypeParameterScopeBuilder,
       {required this.importUri,
@@ -472,14 +478,6 @@
   }
 
   @override
-  List<NominalVariableBuilder> get unboundNominalVariables =>
-      _sourceLibraryBuilder.unboundNominalVariables;
-
-  @override
-  List<StructuralVariableBuilder> get unboundStructuralVariables =>
-      _sourceLibraryBuilder.unboundStructuralVariables;
-
-  @override
   List<NamedTypeBuilder> get unresolvedNamedTypes =>
       _libraryTypeParameterScopeBuilder.unresolvedNamedTypes;
 
@@ -678,10 +676,6 @@
         libraryBuilder.exporters.addAll(part.exporters);
 
         libraryBuilder.nativeMethods.addAll(part.nativeMethods);
-        libraryBuilder.unboundNominalVariables
-            .addAll(part.unboundNominalVariables);
-        libraryBuilder.unboundStructuralVariables
-            .addAll(part.unboundStructuralVariables);
         // Check that the targets are different. This is not normally a problem
         // but is for augmentation libraries.
         if (libraryBuilder.library != part.library &&
@@ -784,6 +778,57 @@
   }
 
   @override
+  void collectUnboundTypeVariables(
+      SourceLibraryBuilder libraryBuilder,
+      Map<NominalVariableBuilder, SourceLibraryBuilder> nominalVariables,
+      Map<StructuralVariableBuilder, SourceLibraryBuilder>
+          structuralVariables) {
+    for (NominalVariableBuilder builder in _unboundNominalVariables) {
+      nominalVariables[builder] = libraryBuilder;
+    }
+    for (StructuralVariableBuilder builder in _unboundStructuralVariables) {
+      structuralVariables[builder] = libraryBuilder;
+    }
+    _unboundStructuralVariables.clear();
+    _unboundNominalVariables.clear();
+  }
+
+  @override
+  List<StructuralVariableBuilder> copyStructuralVariables(
+      List<StructuralVariableBuilder> original,
+      TypeParameterScopeBuilder declaration,
+      {required TypeVariableKind kind}) {
+    List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
+    List<StructuralVariableBuilder> copy = <StructuralVariableBuilder>[];
+    for (StructuralVariableBuilder variable in original) {
+      StructuralVariableBuilder newVariable = new StructuralVariableBuilder(
+          variable.name,
+          _sourceLibraryBuilder,
+          variable.charOffset,
+          variable.fileUri,
+          bound: variable.bound?.clone(newTypes, this, declaration),
+          variableVariance: variable.parameter.isLegacyCovariant
+              ? null
+              :
+              // Coverage-ignore(suite): Not run.
+              variable.variance,
+          isWildcard: variable.isWildcard);
+      copy.add(newVariable);
+      _unboundStructuralVariables.add(newVariable);
+    }
+    for (NamedTypeBuilder newType in newTypes) {
+      declaration.registerUnresolvedNamedType(newType);
+    }
+    return copy;
+  }
+
+  @override
+  void registerUnboundStructuralVariables(
+      List<StructuralVariableBuilder> variableBuilders) {
+    _unboundStructuralVariables.addAll(variableBuilders);
+  }
+
+  @override
   void addPart(OffsetMap offsetMap, Token partKeyword,
       List<MetadataBuilder>? metadata, String uri, int charOffset) {
     Uri resolvedUri = _resolve(this.importUri, uri, charOffset, isPart: true);
@@ -1571,18 +1616,14 @@
             if (supertype is NamedTypeBuilder &&
                 supertype.typeArguments != null) {
               for (int i = 0; i < supertype.typeArguments!.length; ++i) {
-                supertype.typeArguments![i] = supertype.typeArguments![i].clone(
-                    newTypes,
-                    _sourceLibraryBuilder,
-                    currentTypeParameterScopeBuilder);
+                supertype.typeArguments![i] = supertype.typeArguments![i]
+                    .clone(newTypes, this, currentTypeParameterScopeBuilder);
               }
             }
             if (mixin is NamedTypeBuilder && mixin.typeArguments != null) {
               for (int i = 0; i < mixin.typeArguments!.length; ++i) {
-                mixin.typeArguments![i] = mixin.typeArguments![i].clone(
-                    newTypes,
-                    _sourceLibraryBuilder,
-                    currentTypeParameterScopeBuilder);
+                mixin.typeArguments![i] = mixin.typeArguments![i]
+                    .clone(newTypes, this, currentTypeParameterScopeBuilder);
               }
             }
             for (NamedTypeBuilder newType in newTypes) {
@@ -2725,7 +2766,7 @@
         kind: kind,
         isWildcard: libraryFeatures.wildcardVariables.isEnabled && name == '_');
 
-    unboundNominalVariables.add(builder);
+    _unboundNominalVariables.add(builder);
     return builder;
   }
 
@@ -2742,7 +2783,7 @@
         metadata: metadata,
         isWildcard: libraryFeatures.wildcardVariables.isEnabled && name == '_');
 
-    unboundStructuralVariables.add(builder);
+    _unboundStructuralVariables.add(builder);
     return builder;
   }
 
@@ -2817,8 +2858,7 @@
           _sourceLibraryBuilder,
           variable.charOffset,
           variable.fileUri,
-          bound: variable.bound
-              ?.clone(newTypes, _sourceLibraryBuilder, declaration),
+          bound: variable.bound?.clone(newTypes, this, declaration),
           kind: kind,
           variableVariance: variable.parameter.isLegacyCovariant
               ? null
@@ -2827,7 +2867,7 @@
               variable.variance,
           isWildcard: variable.isWildcard);
       copy.add(newVariable);
-      unboundNominalVariables.add(newVariable);
+      _unboundNominalVariables.add(newVariable);
     }
     for (NamedTypeBuilder newType in newTypes) {
       declaration.registerUnresolvedNamedType(newType);
@@ -3072,7 +3112,7 @@
             currentTypeParameterScopeBuilder
                 .registerUnresolvedNamedType(unboundType);
           }
-          this.unboundStructuralVariables.addAll(unboundTypeVariables);
+          this._unboundStructuralVariables.addAll(unboundTypeVariables);
           for (int i = 0; i < variables.length; ++i) {
             variables[i].defaultType = calculatedBounds[i];
           }
diff --git a/pkg/front_end/lib/src/source/source_library_builder.dart b/pkg/front_end/lib/src/source/source_library_builder.dart
index 4e7f85e..c535450 100644
--- a/pkg/front_end/lib/src/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/source/source_library_builder.dart
@@ -165,12 +165,6 @@
 
   final List<SourceFunctionBuilder> nativeMethods = <SourceFunctionBuilder>[];
 
-  final List<NominalVariableBuilder> unboundNominalVariables =
-      <NominalVariableBuilder>[];
-
-  final List<StructuralVariableBuilder> unboundStructuralVariables =
-      <StructuralVariableBuilder>[];
-
   final List<PendingBoundsCheck> _pendingBoundsChecks = [];
   final List<GenericFunctionTypeCheck> _pendingGenericFunctionTypeChecks = [];
 
@@ -1553,55 +1547,30 @@
     return count;
   }
 
-  List<StructuralVariableBuilder> copyStructuralVariables(
-      List<StructuralVariableBuilder> original,
-      TypeParameterScopeBuilder declaration,
-      {required TypeVariableKind kind}) {
-    List<NamedTypeBuilder> newTypes = <NamedTypeBuilder>[];
-    List<StructuralVariableBuilder> copy = <StructuralVariableBuilder>[];
-    for (StructuralVariableBuilder variable in original) {
-      StructuralVariableBuilder newVariable = new StructuralVariableBuilder(
-          variable.name, this, variable.charOffset, variable.fileUri,
-          bound: variable.bound?.clone(newTypes, this, declaration),
-          variableVariance: variable.parameter.isLegacyCovariant
-              ? null
-              :
-              // Coverage-ignore(suite): Not run.
-              variable.variance,
-          isWildcard: variable.isWildcard);
-      copy.add(newVariable);
-      unboundStructuralVariables.add(newVariable);
-    }
-    for (NamedTypeBuilder newType in newTypes) {
-      declaration.registerUnresolvedNamedType(newType);
-    }
-    return copy;
-  }
-
-  /// Adds all [unboundNominalVariables] to [typeVariableBuilders], mapping them
-  /// to this library.
+  /// Adds all unbound nominal variables to [nominalVariables] and unbound
+  /// structural variables to [structuralVariables], mapping them to this
+  /// library.
   ///
   /// This is used to compute the bounds of type variable while taking the
   /// bound dependencies, which might span multiple libraries, into account.
   void collectUnboundTypeVariables(
-      Map<NominalVariableBuilder, SourceLibraryBuilder> typeVariableBuilders,
+      Map<NominalVariableBuilder, SourceLibraryBuilder> nominalVariables,
       Map<StructuralVariableBuilder, SourceLibraryBuilder>
-          functionTypeTypeVariableBuilders) {
+          structuralVariables) {
     Iterable<SourceLibraryBuilder>? augmentationLibraries =
         this.augmentationLibraries;
     if (augmentationLibraries != null) {
       for (SourceLibraryBuilder augmentationLibrary in augmentationLibraries) {
         augmentationLibrary.collectUnboundTypeVariables(
-            typeVariableBuilders, functionTypeTypeVariableBuilders);
+            nominalVariables, structuralVariables);
       }
     }
-    for (NominalVariableBuilder builder in unboundNominalVariables) {
-      typeVariableBuilders[builder] = this;
+    compilationUnit.collectUnboundTypeVariables(
+        this, nominalVariables, structuralVariables);
+    for (SourceCompilationUnit part in parts) {
+      part.collectUnboundTypeVariables(
+          this, nominalVariables, structuralVariables);
     }
-    for (StructuralVariableBuilder builder in unboundStructuralVariables) {
-      functionTypeTypeVariableBuilders[builder] = this;
-    }
-    unboundNominalVariables.clear();
   }
 
   /// Assigns nullabilities to types in [_pendingNullabilities].