Version 2.12.0-154.0.dev

Merge commit '9673d47a063da84a31f1eff9a22278bbfcf666e9' into 'dev'
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 35c074e..4bb99c3 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -949,8 +949,8 @@
       ReusageResult reusedResult, UriTranslator uriTranslator) {
     bool removedDillBuilders = false;
     for (LibraryBuilder builder in reusedResult.notReusedLibraries) {
-      cleanupSourcesForBuilder(
-          builder, uriTranslator, CompilerContext.current.uriToSource);
+      cleanupSourcesForBuilder(reusedResult, builder, uriTranslator,
+          CompilerContext.current.uriToSource);
       incrementalSerializer?.invalidate(builder.fileUri);
 
       LibraryBuilder dillBuilder =
@@ -1494,7 +1494,6 @@
                 getPartFileUri(library.fileUri, part, uriTranslator);
             partsUsed.add(partFileUri);
           }
-          partsUsed;
         }
       }
     }
@@ -1510,7 +1509,7 @@
         if (dillLoadedData.loader.builders.remove(uri) != null) {
           removedDillBuilders = true;
         }
-        cleanupSourcesForBuilder(builder, uriTranslator,
+        cleanupSourcesForBuilder(null, builder, uriTranslator,
             CompilerContext.current.uriToSource, uriToSource, partsUsed);
         userBuilders?.remove(uri);
         removeLibraryFromRemainingComponentProblems(
@@ -1545,15 +1544,43 @@
   /// [partsUsed] indicates part uris that are used by (other/alive) libraries.
   /// Those parts will not be cleaned up. This is useful when a part has been
   /// "moved" to be part of another library.
-  void cleanupSourcesForBuilder(LibraryBuilder builder,
-      UriTranslator uriTranslator, Map<Uri, Source> uriToSource,
-      [Map<Uri, Source> uriToSourceExtra, Set<Uri> partsUsed]) {
+  void cleanupSourcesForBuilder(
+      ReusageResult reusedResult,
+      LibraryBuilder builder,
+      UriTranslator uriTranslator,
+      Map<Uri, Source> uriToSource,
+      [Map<Uri, Source> uriToSourceExtra,
+      Set<Uri> partsUsed]) {
     uriToSource.remove(builder.fileUri);
     uriToSourceExtra?.remove(builder.fileUri);
     Library lib = builder.library;
     for (LibraryPart part in lib.parts) {
       Uri partFileUri = getPartFileUri(lib.fileUri, part, uriTranslator);
       if (partsUsed != null && partsUsed.contains(partFileUri)) continue;
+
+      // If the builders map contain the "parts" import uri, it's a real library
+      // (erroneously) used as a part so we don't want to remove that.
+      if (userCode?.loader != null) {
+        Uri partImportUri = uriToSource[partFileUri]?.importUri;
+        if (partImportUri != null &&
+            userCode.loader.builders.containsKey(partImportUri)) {
+          continue;
+        }
+      } else if (reusedResult != null) {
+        // We've just launched and don't have userCode yet. Search reusedResult
+        // for a kept library with this uri.
+        bool found = false;
+        for (int i = 0; i < reusedResult.reusedLibraries.length; i++) {
+          LibraryBuilder reusedLibrary = reusedResult.reusedLibraries[i];
+          if (reusedLibrary.fileUri == partFileUri) {
+            found = true;
+            break;
+          }
+        }
+        if (found) {
+          continue;
+        }
+      }
       uriToSource.remove(partFileUri);
       uriToSourceExtra?.remove(partFileUri);
     }
diff --git a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
index fdc6b3a..5949536 100644
--- a/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_library_builder.dart
@@ -13,6 +13,9 @@
 import 'package:_fe_analyzer_shared/src/util/resolve_relative_uri.dart'
     show resolveRelativeUri;
 
+import 'package:front_end/src/fasta/dill/dill_library_builder.dart'
+    show DillLibraryBuilder;
+
 import 'package:kernel/ast.dart'
     show
         Arguments,
@@ -179,7 +182,7 @@
   final List<ConstructorReferenceBuilder> constructorReferences =
       <ConstructorReferenceBuilder>[];
 
-  final List<SourceLibraryBuilder> parts = <SourceLibraryBuilder>[];
+  final List<LibraryBuilder> parts = <LibraryBuilder>[];
 
   // Can I use library.parts instead? See SourceLibraryBuilder.addPart.
   final List<int> partOffsets = <int>[];
@@ -1031,7 +1034,7 @@
   void includeParts(Set<Uri> usedParts) {
     Set<Uri> seenParts = new Set<Uri>();
     for (int i = 0; i < parts.length; i++) {
-      SourceLibraryBuilder part = parts[i];
+      LibraryBuilder part = parts[i];
       int partOffset = partOffsets[i];
       if (part == this) {
         addProblem(messagePartOfSelf, -1, noLength, fileUri);
@@ -1059,28 +1062,39 @@
     }
   }
 
-  bool includePart(
-      SourceLibraryBuilder part, Set<Uri> usedParts, int partOffset) {
-    if (part.partOfUri != null) {
-      if (uriIsValid(part.partOfUri) && part.partOfUri != importUri) {
-        // This is an error, but the part is not removed from the list of parts,
-        // so that metadata annotations can be associated with it.
-        addProblem(
-            templatePartOfUriMismatch.withArguments(
-                part.fileUri, importUri, part.partOfUri),
-            partOffset,
-            noLength,
-            fileUri);
-        return false;
-      }
-    } else if (part.partOfName != null) {
-      if (name != null) {
-        if (part.partOfName != name) {
+  bool includePart(LibraryBuilder part, Set<Uri> usedParts, int partOffset) {
+    if (part is SourceLibraryBuilder) {
+      if (part.partOfUri != null) {
+        if (uriIsValid(part.partOfUri) && part.partOfUri != importUri) {
           // This is an error, but the part is not removed from the list of
           // parts, so that metadata annotations can be associated with it.
           addProblem(
-              templatePartOfLibraryNameMismatch.withArguments(
-                  part.fileUri, name, part.partOfName),
+              templatePartOfUriMismatch.withArguments(
+                  part.fileUri, importUri, part.partOfUri),
+              partOffset,
+              noLength,
+              fileUri);
+          return false;
+        }
+      } else if (part.partOfName != null) {
+        if (name != null) {
+          if (part.partOfName != name) {
+            // This is an error, but the part is not removed from the list of
+            // parts, so that metadata annotations can be associated with it.
+            addProblem(
+                templatePartOfLibraryNameMismatch.withArguments(
+                    part.fileUri, name, part.partOfName),
+                partOffset,
+                noLength,
+                fileUri);
+            return false;
+          }
+        } else {
+          // This is an error, but the part is not removed from the list of
+          // parts, so that metadata annotations can be associated with it.
+          addProblem(
+              templatePartOfUseUri.withArguments(
+                  part.fileUri, fileUri, part.partOfName),
               partOffset,
               noLength,
               fileUri);
@@ -1089,119 +1103,124 @@
       } else {
         // This is an error, but the part is not removed from the list of parts,
         // so that metadata annotations can be associated with it.
-        addProblem(
-            templatePartOfUseUri.withArguments(
-                part.fileUri, fileUri, part.partOfName),
-            partOffset,
-            noLength,
-            fileUri);
+        assert(!part.isPart);
+        if (uriIsValid(part.fileUri)) {
+          addProblem(templateMissingPartOf.withArguments(part.fileUri),
+              partOffset, noLength, fileUri);
+        }
         return false;
       }
+
+      // Language versions have to match. Except if (at least) one of them is
+      // invalid in which case we've already gotten an error about this.
+      if (languageVersion != part.languageVersion &&
+          languageVersion.valid &&
+          part.languageVersion.valid) {
+        // This is an error, but the part is not removed from the list of
+        // parts, so that metadata annotations can be associated with it.
+        List<LocatedMessage> context = <LocatedMessage>[];
+        if (languageVersion.isExplicit) {
+          context.add(messageLanguageVersionLibraryContext.withLocation(
+              languageVersion.fileUri,
+              languageVersion.charOffset,
+              languageVersion.charCount));
+        }
+        if (part.languageVersion.isExplicit) {
+          context.add(messageLanguageVersionPartContext.withLocation(
+              part.languageVersion.fileUri,
+              part.languageVersion.charOffset,
+              part.languageVersion.charCount));
+        }
+        addProblem(
+            messageLanguageVersionMismatchInPart, partOffset, noLength, fileUri,
+            context: context);
+      }
+
+      part.validatePart(this, usedParts);
+      NameIterator partDeclarations = part.nameIterator;
+      while (partDeclarations.moveNext()) {
+        String name = partDeclarations.name;
+        Builder declaration = partDeclarations.current;
+
+        if (declaration.next != null) {
+          List<Builder> duplicated = <Builder>[];
+          while (declaration.next != null) {
+            duplicated.add(declaration);
+            partDeclarations.moveNext();
+            declaration = partDeclarations.current;
+          }
+          duplicated.add(declaration);
+          // Handle duplicated declarations in the part.
+          //
+          // Duplicated declarations are handled by creating a linked list using
+          // the `next` field. This is preferred over making all scope entries
+          // be a `List<Declaration>`.
+          //
+          // We maintain the linked list so that the last entry is easy to
+          // recognize (it's `next` field is null). This means that it is
+          // reversed with respect to source code order. Since kernel doesn't
+          // allow duplicated declarations, we ensure that we only add the first
+          // declaration to the kernel tree.
+          //
+          // Since the duplicated declarations are stored in reverse order, we
+          // iterate over them in reverse order as this is simpler and normally
+          // not a problem. However, in this case we need to call [addBuilder]
+          // in source order as it would otherwise create cycles.
+          //
+          // We also need to be careful preserving the order of the links. The
+          // part library still keeps these declarations in its scope so that
+          // DietListener can find them.
+          for (int i = duplicated.length; i > 0; i--) {
+            Builder declaration = duplicated[i - 1];
+            // No reference: There should be no duplicates when using
+            // references.
+            addBuilder(name, declaration, declaration.charOffset);
+          }
+        } else {
+          // No reference: The part is in the same loader so the reference
+          // - if needed - was already added.
+          addBuilder(name, declaration, declaration.charOffset);
+        }
+      }
+      types.addAll(part.types);
+      constructorReferences.addAll(part.constructorReferences);
+      part.partOfLibrary = this;
+      part.scope.becomePartOf(scope);
+      // TODO(ahe): Include metadata from part?
+
+      nativeMethods.addAll(part.nativeMethods);
+      boundlessTypeVariables.addAll(part.boundlessTypeVariables);
+      // Check that the targets are different. This is not normally a problem
+      // but is for patch files.
+      if (library != part.library && part.library.problemsAsJson != null) {
+        library.problemsAsJson ??= <String>[];
+        library.problemsAsJson.addAll(part.library.problemsAsJson);
+      }
+      List<FieldBuilder> partImplicitlyTypedFields =
+          part.takeImplicitlyTypedFields();
+      if (partImplicitlyTypedFields != null) {
+        if (_implicitlyTypedFields == null) {
+          _implicitlyTypedFields = partImplicitlyTypedFields;
+        } else {
+          _implicitlyTypedFields.addAll(partImplicitlyTypedFields);
+        }
+      }
+      return true;
     } else {
-      // This is an error, but the part is not removed from the list of parts,
-      // so that metadata annotations can be associated with it.
-      assert(!part.isPart);
+      assert(part is DillLibraryBuilder);
+      // Trying to add a dill library builder as a part means that it exists
+      // as a stand-alone library in the dill file.
+      // This means, that it's not a part (if it had been it would be been
+      // "merged in" to the real library and thus not been a library on its own)
+      // so we behave like if it's a library with a missing "part of"
+      // declaration (i.e. as it was a SourceLibraryBuilder without a "part of"
+      // declaration).
       if (uriIsValid(part.fileUri)) {
         addProblem(templateMissingPartOf.withArguments(part.fileUri),
             partOffset, noLength, fileUri);
       }
       return false;
     }
-
-    // Language versions have to match. Except if (at least) one of them is
-    // invalid in which case we've already gotten an error about this.
-    if (languageVersion != part.languageVersion &&
-        languageVersion.valid &&
-        part.languageVersion.valid) {
-      // This is an error, but the part is not removed from the list of
-      // parts, so that metadata annotations can be associated with it.
-      List<LocatedMessage> context = <LocatedMessage>[];
-      if (languageVersion.isExplicit) {
-        context.add(messageLanguageVersionLibraryContext.withLocation(
-            languageVersion.fileUri,
-            languageVersion.charOffset,
-            languageVersion.charCount));
-      }
-      if (part.languageVersion.isExplicit) {
-        context.add(messageLanguageVersionPartContext.withLocation(
-            part.languageVersion.fileUri,
-            part.languageVersion.charOffset,
-            part.languageVersion.charCount));
-      }
-      addProblem(
-          messageLanguageVersionMismatchInPart, partOffset, noLength, fileUri,
-          context: context);
-    }
-
-    part.validatePart(this, usedParts);
-    NameIterator partDeclarations = part.nameIterator;
-    while (partDeclarations.moveNext()) {
-      String name = partDeclarations.name;
-      Builder declaration = partDeclarations.current;
-
-      if (declaration.next != null) {
-        List<Builder> duplicated = <Builder>[];
-        while (declaration.next != null) {
-          duplicated.add(declaration);
-          partDeclarations.moveNext();
-          declaration = partDeclarations.current;
-        }
-        duplicated.add(declaration);
-        // Handle duplicated declarations in the part.
-        //
-        // Duplicated declarations are handled by creating a linked list using
-        // the `next` field. This is preferred over making all scope entries be
-        // a `List<Declaration>`.
-        //
-        // We maintain the linked list so that the last entry is easy to
-        // recognize (it's `next` field is null). This means that it is
-        // reversed with respect to source code order. Since kernel doesn't
-        // allow duplicated declarations, we ensure that we only add the first
-        // declaration to the kernel tree.
-        //
-        // Since the duplicated declarations are stored in reverse order, we
-        // iterate over them in reverse order as this is simpler and normally
-        // not a problem. However, in this case we need to call [addBuilder] in
-        // source order as it would otherwise create cycles.
-        //
-        // We also need to be careful preserving the order of the links. The
-        // part library still keeps these declarations in its scope so that
-        // DietListener can find them.
-        for (int i = duplicated.length; i > 0; i--) {
-          Builder declaration = duplicated[i - 1];
-          // No reference: There should be no duplicates when using references.
-          addBuilder(name, declaration, declaration.charOffset);
-        }
-      } else {
-        // No reference: The part is in the same loader so the reference
-        // - if needed - was already added.
-        addBuilder(name, declaration, declaration.charOffset);
-      }
-    }
-    types.addAll(part.types);
-    constructorReferences.addAll(part.constructorReferences);
-    part.partOfLibrary = this;
-    part.scope.becomePartOf(scope);
-    // TODO(ahe): Include metadata from part?
-
-    nativeMethods.addAll(part.nativeMethods);
-    boundlessTypeVariables.addAll(part.boundlessTypeVariables);
-    // Check that the targets are different. This is not normally a problem
-    // but is for patch files.
-    if (library != part.library && part.library.problemsAsJson != null) {
-      library.problemsAsJson ??= <String>[];
-      library.problemsAsJson.addAll(part.library.problemsAsJson);
-    }
-    List<FieldBuilder> partImplicitlyTypedFields =
-        part.takeImplicitlyTypedFields();
-    if (partImplicitlyTypedFields != null) {
-      if (_implicitlyTypedFields == null) {
-        _implicitlyTypedFields = partImplicitlyTypedFields;
-      } else {
-        _implicitlyTypedFields.addAll(partImplicitlyTypedFields);
-      }
-    }
-    return true;
   }
 
   void buildInitialScopes() {
@@ -2733,8 +2752,10 @@
       }
     }
 
-    for (SourceLibraryBuilder part in parts) {
-      part.addDependencies(library, seen);
+    for (LibraryBuilder part in parts) {
+      if (part is SourceLibraryBuilder) {
+        part.addDependencies(library, seen);
+      }
     }
   }
 
diff --git a/pkg/front_end/lib/src/fasta/source/source_loader.dart b/pkg/front_end/lib/src/fasta/source/source_loader.dart
index 3ec6fc8..86097cd 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -457,7 +457,7 @@
       DietListener listener = createDietListener(library);
       DietParser parser = new DietParser(listener);
       parser.parseUnit(tokens);
-      for (SourceLibraryBuilder part in library.parts) {
+      for (LibraryBuilder part in library.parts) {
         if (part.partOfLibrary != library) {
           // Part was included in multiple libraries. Skip it here.
           continue;
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 9b992fb..b11f1d8 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -600,6 +600,7 @@
 lang
 largest
 lattice
+launched
 launcher
 layer
 layout
@@ -1060,6 +1061,7 @@
 stacktrace
 stacktraces
 stale
+stand
 starter
 statics
 stderr
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml
new file mode 100644
index 0000000..4d3aaaf
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml
@@ -0,0 +1,23 @@
+# Copyright (c) 2020, 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.md file.
+
+type: newworld
+worlds:
+  - entry: main.dart
+    errors: true
+    sources:
+      main.dart: |
+        part 'lib.dart';
+        main() {}
+      lib.dart: |
+        methodFromLib() {}
+    expectedLibraryCount: 2
+
+  - entry: main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.1.expect
new file mode 100644
index 0000000..bf0e799
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.1.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "org-dartlang-test:///lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "org-dartlang-test:///main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.2.expect
new file mode 100644
index 0000000..bf0e799
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of.yaml.world.2.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "org-dartlang-test:///lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "org-dartlang-test:///main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml
new file mode 100644
index 0000000..c27961a
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml
@@ -0,0 +1,25 @@
+# Copyright (c) 2020, 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.md file.
+
+type: newworld
+worlds:
+  - entry: package:foo/main.dart
+    errors: true
+    sources:
+      .packages: |
+        foo:.
+      main.dart: |
+        part 'lib.dart';
+        main() {}
+      lib.dart: |
+        methodFromLib() {}
+    expectedLibraryCount: 2
+
+  - entry: package:foo/main.dart
+    errors: true
+    worldType: updated
+    expectInitializeFromDill: false
+    invalidate:
+      - main.dart
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.1.expect
new file mode 100644
index 0000000..fc6881c
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.1.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "package:foo/lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "package:foo/main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.2.expect
new file mode 100644
index 0000000..fc6881c
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_as_package.yaml.world.2.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "package:foo/lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "package:foo/main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml
new file mode 100644
index 0000000..6be47bd
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml
@@ -0,0 +1,27 @@
+# Copyright (c) 2020, 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.md file.
+
+type: newworld
+worlds:
+  - entry: main.dart
+    errors: true
+    sources:
+      main.dart: |
+        part 'lib.dart';
+        main() {}
+      lib.dart: |
+        methodFromLib() {}
+    expectedLibraryCount: 2
+
+  - entry: main.dart
+    errors: true
+    invalidate:
+      - main.dart
+    sources:
+      main.dart: |
+        part 'lib.dart';
+        main() {}
+      lib.dart: |
+        methodFromLib() {}
+    expectedLibraryCount: 2
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.1.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.1.expect
new file mode 100644
index 0000000..bf0e799
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.1.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "org-dartlang-test:///lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "org-dartlang-test:///main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.2.expect b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.2.expect
new file mode 100644
index 0000000..bf0e799
--- /dev/null
+++ b/pkg/front_end/testcases/incremental_initialize_from_dill/part_not_part_of_initialized_from_dill.yaml.world.2.expect
@@ -0,0 +1,17 @@
+main = main::main;
+library from "org-dartlang-test:///lib.dart" as lib {
+
+  static method methodFromLib() → dynamic {}
+}
+library from "org-dartlang-test:///main.dart" as main {
+//
+// Problems in library:
+//
+// org-dartlang-test:///main.dart:1:6: Error: Can't use 'org-dartlang-test:///lib.dart' as a part, because it has no 'part of' declaration.
+// part 'lib.dart';
+//      ^
+//
+
+  part lib.dart;
+  static method main() → dynamic {}
+}
diff --git a/tools/VERSION b/tools/VERSION
index d1e4aec..6e6e5813 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 12
 PATCH 0
-PRERELEASE 153
+PRERELEASE 154
 PRERELEASE_PATCH 0
\ No newline at end of file