[CFE][kernel] Add 'invalid' nnbd mode; use when trying to out out when compiling in strong mode

Change-Id: I3d1a8da4378cd59e733fc796df38ae98aaf59d6d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/169881
Commit-Queue: Jens Johansen <jensj@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 177e1ae..6bce0eb 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -162,6 +162,26 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeAgnosticWithStrongDillLibrary =
+    messageAgnosticWithStrongDillLibrary;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageAgnosticWithStrongDillLibrary = const MessageCode(
+    "AgnosticWithStrongDillLibrary",
+    message:
+        r"""Loaded library is compiled with sound null safety and cannot be used in compilation for agnostic null safety.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeAgnosticWithWeakDillLibrary =
+    messageAgnosticWithWeakDillLibrary;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageAgnosticWithWeakDillLibrary = const MessageCode(
+    "AgnosticWithWeakDillLibrary",
+    message:
+        r"""Loaded library is compiled with unsound null safety and cannot be used in compilation for agnostic null safety.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeAmbiguousExtensionCause = messageAmbiguousExtensionCause;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -5623,6 +5643,14 @@
         r"""Try changing the inline function type (as in 'int f()') to a prefixed function type using the `Function` keyword (as in 'int Function() f').""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeInvalidNnbdDillLibrary = messageInvalidNnbdDillLibrary;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageInvalidNnbdDillLibrary = const MessageCode(
+    "InvalidNnbdDillLibrary",
+    message: r"""Trying to use library with invalid null safety.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<Message Function(Token token)> templateInvalidOperator =
     const Template<Message Function(Token token)>(
         messageTemplate:
@@ -8720,6 +8748,16 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeStrongWithWeakDillLibrary =
+    messageStrongWithWeakDillLibrary;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageStrongWithWeakDillLibrary = const MessageCode(
+    "StrongWithWeakDillLibrary",
+    message:
+        r"""Loaded library is compiled with unsound null safety and cannot be used in compilation for sound null safety.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeSuperAsExpression = messageSuperAsExpression;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
@@ -9689,6 +9727,16 @@
     tip: r"""Try removing the type arguments.""");
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<Null> codeWeakWithStrongDillLibrary =
+    messageWeakWithStrongDillLibrary;
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const MessageCode messageWeakWithStrongDillLibrary = const MessageCode(
+    "WeakWithStrongDillLibrary",
+    message:
+        r"""Loaded library is compiled with sound null safety and cannot be used in compilation for unsound null safety.""");
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Template<
     Message Function(
         String string,
diff --git a/pkg/front_end/lib/src/base/processed_options.dart b/pkg/front_end/lib/src/base/processed_options.dart
index b45bbcf..e6ee21b 100644
--- a/pkg/front_end/lib/src/base/processed_options.dart
+++ b/pkg/front_end/lib/src/base/processed_options.dart
@@ -374,6 +374,12 @@
   }
 
   Component _validateNullSafetyMode(Component component) {
+    if (component.mode == NonNullableByDefaultCompiledMode.Invalid) {
+      throw new FormatException(
+          'Provided .dill file for the following libraries has an invalid null '
+          'safety mode and does not support null safety:\n'
+          '${component.libraries.join('\n')}');
+    }
     if (nnbdMode == NnbdMode.Strong &&
         !(component.mode == NonNullableByDefaultCompiledMode.Strong ||
             component.mode == NonNullableByDefaultCompiledMode.Agnostic)) {
diff --git a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
index 4917f03..cf98a1f 100644
--- a/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
+++ b/pkg/front_end/lib/src/fasta/dill/dill_loader.dart
@@ -6,13 +6,7 @@
 
 import 'dart:async' show Future;
 
-import 'package:front_end/src/api_prototype/experimental_flags.dart'
-    show ExperimentalFlag;
-import 'package:front_end/src/base/nnbd_mode.dart' show NnbdMode;
-import 'package:kernel/ast.dart'
-    show Class, Component, DartType, Library, NonNullableByDefaultCompiledMode;
-import 'package:kernel/binary/ast_from_binary.dart'
-    show mergeCompilationModeOrThrow;
+import 'package:kernel/ast.dart' show Class, Component, DartType, Library;
 
 import '../builder/class_builder.dart';
 import '../builder/library_builder.dart';
@@ -55,8 +49,6 @@
       Library library = componentLibraries[i];
       Uri uri = library.importUri;
       if (filter == null || filter(library.importUri)) {
-        assert(
-            _checkNNBDSetting(library), "Unexpected NNBD setting for library");
         libraries.add(library);
         target.addLibrary(library);
         requestedLibraries.add(uri);
@@ -124,32 +116,4 @@
   TypeBuilder computeTypeBuilder(DartType type) {
     return type.accept(new TypeBuilderComputer(this));
   }
-
-  bool _checkNNBDSetting(Library library) {
-    // Compute "output nnbd mode".
-    NonNullableByDefaultCompiledMode compiledMode;
-    if (target.context.options
-        .isExperimentEnabledGlobally(ExperimentalFlag.nonNullable)) {
-      switch (target.context.options.nnbdMode) {
-        case NnbdMode.Weak:
-          compiledMode = NonNullableByDefaultCompiledMode.Weak;
-          break;
-        case NnbdMode.Strong:
-          compiledMode = NonNullableByDefaultCompiledMode.Strong;
-          break;
-        case NnbdMode.Agnostic:
-          compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
-          break;
-      }
-    } else {
-      compiledMode = NonNullableByDefaultCompiledMode.Weak;
-    }
-
-    if (compiledMode !=
-        mergeCompilationModeOrThrow(
-            compiledMode, library.nonNullableByDefaultCompiledMode)) {
-      return false;
-    }
-    return true;
-  }
 }
diff --git a/pkg/front_end/lib/src/fasta/incremental_compiler.dart b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
index 6f28cdb..69d3f19 100644
--- a/pkg/front_end/lib/src/fasta/incremental_compiler.dart
+++ b/pkg/front_end/lib/src/fasta/incremental_compiler.dart
@@ -785,13 +785,49 @@
     dillLoadedData.loader.currentSourceLoader = userCode.loader;
 
     // Re-use the libraries we've deemed re-usable.
+    List<bool> seenModes = [false, false, false, false];
     for (LibraryBuilder library in reusedLibraries) {
+      seenModes[library.library.nonNullableByDefaultCompiledMode.index] = true;
       userCode.loader.builders[library.importUri] = library;
       if (library.importUri.scheme == "dart" &&
           library.importUri.path == "core") {
         userCode.loader.coreLibrary = library;
       }
     }
+    // Check compilation mode up against what we've seen here and set
+    // `hasInvalidNnbdModeLibrary` accordingly.
+    if (c.options.isExperimentEnabledGlobally(ExperimentalFlag.nonNullable)) {
+      switch (c.options.nnbdMode) {
+        case NnbdMode.Weak:
+          // Don't expect strong or invalid.
+          if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
+              seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
+            userCode.loader.hasInvalidNnbdModeLibrary = true;
+          }
+          break;
+        case NnbdMode.Strong:
+          // Don't expect weak or invalid.
+          if (seenModes[NonNullableByDefaultCompiledMode.Weak.index] ||
+              seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
+            userCode.loader.hasInvalidNnbdModeLibrary = true;
+          }
+          break;
+        case NnbdMode.Agnostic:
+          // Don't expect strong, weak or invalid.
+          if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
+              seenModes[NonNullableByDefaultCompiledMode.Weak.index] ||
+              seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
+            userCode.loader.hasInvalidNnbdModeLibrary = true;
+          }
+          break;
+      }
+    } else {
+      // Don't expect strong or invalid.
+      if (seenModes[NonNullableByDefaultCompiledMode.Strong.index] ||
+          seenModes[NonNullableByDefaultCompiledMode.Invalid.index]) {
+        userCode.loader.hasInvalidNnbdModeLibrary = true;
+      }
+    }
 
     // The entry point(s) has to be set first for loader.first to be setup
     // correctly. If the first one is in the rebuildBodies, we have to add it
@@ -1595,6 +1631,9 @@
             // For now just don't initialize from this dill.
             throw const PackageChangedError();
           }
+          // Note: If a library has a NonNullableByDefaultCompiledMode.invalid
+          // we will throw and we won't initialize from it.
+          // That's wanted behavior.
           if (compiledMode !=
               mergeCompilationModeOrThrow(
                   compiledMode, lib.nonNullableByDefaultCompiledMode)) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
index 17161dfb..ba8a8b3 100644
--- a/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/kernel_target.dart
@@ -7,6 +7,8 @@
 import 'dart:async' show Future;
 
 import 'package:front_end/src/api_prototype/experimental_flags.dart';
+import 'package:front_end/src/fasta/dill/dill_library_builder.dart'
+    show DillLibraryBuilder;
 import 'package:kernel/ast.dart'
     show
         Arguments,
@@ -39,28 +41,20 @@
         TypeParameterType,
         VariableDeclaration,
         VariableGet;
-
 import 'package:kernel/class_hierarchy.dart' show ClassHierarchy;
-
 import 'package:kernel/clone.dart' show CloneVisitorNotMembers;
-
 import 'package:kernel/core_types.dart';
-
 import 'package:kernel/reference_from_index.dart' show IndexedClass;
-
-import 'package:kernel/type_algebra.dart' show substitute;
 import 'package:kernel/target/changed_structure_notifier.dart'
     show ChangedStructureNotifier;
 import 'package:kernel/target/targets.dart' show DiagnosticReporter;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
-
 import 'package:kernel/transformations/value_class.dart' as valueClass;
-
+import 'package:kernel/type_algebra.dart' show substitute;
+import 'package:kernel/type_environment.dart' show TypeEnvironment;
 import 'package:package_config/package_config.dart';
 
 import '../../api_prototype/file_system.dart' show FileSystem;
 import '../../base/nnbd_mode.dart';
-
 import '../builder/builder.dart';
 import '../builder/class_builder.dart';
 import '../builder/constructor_builder.dart';
@@ -78,27 +72,25 @@
 import '../builder/type_declaration_builder.dart';
 import '../builder/type_variable_builder.dart';
 import '../builder/void_type_declaration_builder.dart';
-
 import '../compiler_context.dart' show CompilerContext;
-
 import '../crash.dart' show withCrashReporting;
-
-import '../dill/dill_target.dart' show DillTarget;
-
 import '../dill/dill_member_builder.dart' show DillMemberBuilder;
-
-import '../fasta_codes.dart' show Message, LocatedMessage;
-
+import '../dill/dill_target.dart' show DillTarget;
+import '../fasta_codes.dart' show LocatedMessage, Message;
 import '../loader.dart' show Loader;
-
 import '../messages.dart'
     show
         FormattedMessage,
+        messageAgnosticWithStrongDillLibrary,
+        messageAgnosticWithWeakDillLibrary,
         messageConstConstructorLateFinalFieldCause,
         messageConstConstructorLateFinalFieldError,
         messageConstConstructorNonFinalField,
         messageConstConstructorNonFinalFieldCause,
         messageConstConstructorRedirectionToNonConst,
+        messageInvalidNnbdDillLibrary,
+        messageStrongWithWeakDillLibrary,
+        messageWeakWithStrongDillLibrary,
         noLength,
         templateFieldNonNullableNotInitializedByConstructorError,
         templateFieldNonNullableWithoutInitializerError,
@@ -107,28 +99,17 @@
         templateInferredPackageUri,
         templateMissingImplementationCause,
         templateSuperclassHasNoDefaultConstructor;
-
 import '../problems.dart' show unhandled;
-
 import '../scope.dart' show AmbiguousBuilder;
-
 import '../source/source_class_builder.dart' show SourceClassBuilder;
-
 import '../source/source_library_builder.dart' show SourceLibraryBuilder;
-
 import '../source/source_loader.dart' show SourceLoader;
-
 import '../target_implementation.dart' show TargetImplementation;
-
 import '../uri_translator.dart' show UriTranslator;
-
 import 'constant_evaluator.dart' as constants
     show EvaluationMode, transformLibraries, transformProcedure;
-
 import 'kernel_constants.dart' show KernelConstantErrorReporter;
-
 import 'metadata_collector.dart' show MetadataCollector;
-
 import 'verifier.dart' show verifyComponent, verifyGetStaticType;
 
 class KernelTarget extends TargetImplementation {
@@ -273,10 +254,44 @@
     if (dillTarget.isLoaded) {
       LibraryBuilder builder = dillTarget.loader.builders[uri];
       if (builder != null) {
-        if (loader.nnbdMode == NnbdMode.Strong ||
-            loader.nnbdMode == NnbdMode.Agnostic) {
-          if (!builder.isNonNullableByDefault) {
-            loader.registerStrongOptOutLibrary(builder);
+        if (!builder.isNonNullableByDefault &&
+            (loader.nnbdMode == NnbdMode.Strong ||
+                loader.nnbdMode == NnbdMode.Agnostic)) {
+          loader.registerStrongOptOutLibrary(builder);
+        } else if (builder is DillLibraryBuilder) {
+          NonNullableByDefaultCompiledMode libraryMode =
+              builder.library.nonNullableByDefaultCompiledMode;
+          if (libraryMode == NonNullableByDefaultCompiledMode.Invalid) {
+            loader.registerNnbdMismatchLibrary(
+                builder, messageInvalidNnbdDillLibrary);
+          } else {
+            switch (loader.nnbdMode) {
+              case NnbdMode.Weak:
+                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+                    libraryMode != NonNullableByDefaultCompiledMode.Weak) {
+                  loader.registerNnbdMismatchLibrary(
+                      builder, messageWeakWithStrongDillLibrary);
+                }
+                break;
+              case NnbdMode.Strong:
+                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic &&
+                    libraryMode != NonNullableByDefaultCompiledMode.Strong) {
+                  loader.registerNnbdMismatchLibrary(
+                      builder, messageStrongWithWeakDillLibrary);
+                }
+                break;
+              case NnbdMode.Agnostic:
+                if (libraryMode != NonNullableByDefaultCompiledMode.Agnostic) {
+                  if (libraryMode == NonNullableByDefaultCompiledMode.Strong) {
+                    loader.registerNnbdMismatchLibrary(
+                        builder, messageAgnosticWithStrongDillLibrary);
+                  } else {
+                    loader.registerNnbdMismatchLibrary(
+                        builder, messageAgnosticWithWeakDillLibrary);
+                  }
+                }
+                break;
+            }
           }
         }
         return builder;
@@ -441,6 +456,9 @@
     } else {
       compiledMode = NonNullableByDefaultCompiledMode.Weak;
     }
+    if (loader.hasInvalidNnbdModeLibrary) {
+      compiledMode = NonNullableByDefaultCompiledMode.Invalid;
+    }
 
     Reference mainReference;
 
@@ -464,11 +482,88 @@
     if (metadataCollector != null) {
       component.addMetadataRepository(metadataCollector.repository);
     }
+    assert(_getLibraryNnbdModeError(component) == null,
+        "Got error: ${_getLibraryNnbdModeError(component)}");
 
     ticker.logMs("Linked component");
     return component;
   }
 
+  String _getLibraryNnbdModeError(Component component) {
+    if (loader.hasInvalidNnbdModeLibrary) {
+      // At least 1 library should be invalid or there should be a mix of strong
+      // and weak. For libraries we've just compiled it will be marked as
+      // invalid, but for libraries loaded from dill they have their original
+      // value (i.e. either strong or weak).
+      bool foundInvalid = false;
+      bool foundStrong = false;
+      bool foundWeak = false;
+      for (Library library in component.libraries) {
+        if (library.nonNullableByDefaultCompiledMode ==
+            NonNullableByDefaultCompiledMode.Invalid) {
+          foundInvalid = true;
+          break;
+        } else if (!foundWeak &&
+            library.nonNullableByDefaultCompiledMode ==
+                NonNullableByDefaultCompiledMode.Weak) {
+          foundWeak = true;
+          if (foundStrong) break;
+        } else if (!foundStrong &&
+            library.nonNullableByDefaultCompiledMode ==
+                NonNullableByDefaultCompiledMode.Strong) {
+          foundStrong = true;
+          if (foundWeak) break;
+        }
+      }
+      if (!foundInvalid && !(foundStrong && foundWeak)) {
+        return "hasInvalidNnbdModeLibrary is true, but no library was invalid "
+            "and there was no weak/strong mix.";
+      }
+      if (component.mode != NonNullableByDefaultCompiledMode.Invalid) {
+        return "Component mode is not invalid as expected";
+      }
+    } else {
+      // No libraries are allowed to be invalid, and should all be compatible
+      // with the component nnbd mode setting.
+      if (component.mode == NonNullableByDefaultCompiledMode.Invalid) {
+        return "Component mode is invalid which was not expected";
+      }
+      if (component.modeRaw == null) {
+        return "Component mode not set at all";
+      }
+      for (Library library in component.libraries) {
+        if (component.mode == NonNullableByDefaultCompiledMode.Strong) {
+          if (library.nonNullableByDefaultCompiledMode !=
+                  NonNullableByDefaultCompiledMode.Strong &&
+              library.nonNullableByDefaultCompiledMode !=
+                  NonNullableByDefaultCompiledMode.Agnostic) {
+            return "Expected library ${library.importUri} to be strong or "
+                "agnostic, but was ${library.nonNullableByDefaultCompiledMode}";
+          }
+        } else if (component.mode == NonNullableByDefaultCompiledMode.Weak) {
+          if (library.nonNullableByDefaultCompiledMode !=
+                  NonNullableByDefaultCompiledMode.Weak &&
+              library.nonNullableByDefaultCompiledMode !=
+                  NonNullableByDefaultCompiledMode.Agnostic) {
+            return "Expected library ${library.importUri} to be weak or "
+                "agnostic, but was ${library.nonNullableByDefaultCompiledMode}";
+          }
+        } else if (component.mode ==
+            NonNullableByDefaultCompiledMode.Agnostic) {
+          if (library.nonNullableByDefaultCompiledMode !=
+              NonNullableByDefaultCompiledMode.Agnostic) {
+            return "Expected library ${library.importUri} to be agnostic, "
+                "but was ${library.nonNullableByDefaultCompiledMode}";
+          }
+        } else {
+          return "Expected component mode to be either strong, "
+              "weak or agnostic but was ${component.mode}";
+        }
+      }
+    }
+    return null;
+  }
+
   void installDefaultSupertypes() {
     Class objectClass = this.objectClass;
     loader.builders.forEach((Uri uri, LibraryBuilder library) {
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 badb049..b70ba48 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
@@ -487,19 +487,20 @@
   LanguageVersion get languageVersion => _languageVersion;
 
   void markLanguageVersionFinal() {
-    if (enableNonNullableInLibrary &&
+    if (!isNonNullableByDefault &&
         (loader.nnbdMode == NnbdMode.Strong ||
             loader.nnbdMode == NnbdMode.Agnostic)) {
       // In strong and agnostic mode, the language version is not allowed to
       // opt a library out of nnbd.
-      if (!isNonNullableByDefault) {
-        if (_languageVersion.isExplicit) {
-          addPostponedProblem(messageStrongModeNNBDButOptOut,
-              _languageVersion.charOffset, _languageVersion.charCount, fileUri);
-        } else {
-          loader.registerStrongOptOutLibrary(this);
-        }
+      if (_languageVersion.isExplicit) {
+        addPostponedProblem(messageStrongModeNNBDButOptOut,
+            _languageVersion.charOffset, _languageVersion.charCount, fileUri);
+      } else {
+        loader.registerStrongOptOutLibrary(this);
       }
+      library.nonNullableByDefaultCompiledMode =
+          NonNullableByDefaultCompiledMode.Invalid;
+      loader.hasInvalidNnbdModeLibrary = true;
     }
     _languageVersion.isFinal = true;
     _ensureIsNonNullableByDefault();
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 a8a4a63..215bba5 100644
--- a/pkg/front_end/lib/src/fasta/source/source_loader.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_loader.dart
@@ -323,6 +323,18 @@
   void registerStrongOptOutLibrary(LibraryBuilder libraryBuilder) {
     _strongOptOutLibraries ??= {};
     _strongOptOutLibraries.add(libraryBuilder);
+    hasInvalidNnbdModeLibrary = true;
+  }
+
+  bool hasInvalidNnbdModeLibrary = false;
+
+  Map<LibraryBuilder, Message> _nnbdMismatchLibraries;
+
+  void registerNnbdMismatchLibrary(
+      LibraryBuilder libraryBuilder, Message message) {
+    _nnbdMismatchLibraries ??= {};
+    _nnbdMismatchLibraries[libraryBuilder] = message;
+    hasInvalidNnbdModeLibrary = true;
   }
 
   @override
@@ -395,6 +407,13 @@
         _strongOptOutLibraries = null;
       }
     }
+    if (_nnbdMismatchLibraries != null) {
+      for (MapEntry<LibraryBuilder, Message> entry
+          in _nnbdMismatchLibraries.entries) {
+        addProblem(entry.value, -1, noLength, entry.key.fileUri);
+      }
+      _nnbdMismatchLibraries = null;
+    }
   }
 
   List<int> getSource(List<int> bytes) {
diff --git a/pkg/front_end/lib/src/kernel_generator_impl.dart b/pkg/front_end/lib/src/kernel_generator_impl.dart
index 66dbc7b..78a0c68 100644
--- a/pkg/front_end/lib/src/kernel_generator_impl.dart
+++ b/pkg/front_end/lib/src/kernel_generator_impl.dart
@@ -138,6 +138,9 @@
           compiledMode = NonNullableByDefaultCompiledMode.Agnostic;
           break;
       }
+      if (kernelTarget.loader.hasInvalidNnbdModeLibrary) {
+        compiledMode = NonNullableByDefaultCompiledMode.Invalid;
+      }
 
       trimmedSummaryComponent.setMainMethodAndMode(
           trimmedSummaryComponent.mainMethodName, false, compiledMode);
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index 5dad4ce..329faa1 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -14,6 +14,11 @@
 AbstractRedirectedClassInstantiation/example: Fail
 AccessError/analyzerCode: Fail
 AccessError/example: Fail
+AgnosticWithStrongDillLibrary/analyzerCode: Fail
+AgnosticWithStrongDillLibrary/example: Fail
+AgnosticWithWeakDillLibrary/analyzerCode: Fail
+AgnosticWithWeakDillLibrary/example: Fail
+AgnosticWithWeakDillLibrary/spelling: Fail
 AmbiguousExtensionMethod/analyzerCode: Fail
 AmbiguousExtensionOperator/analyzerCode: Fail
 AmbiguousExtensionProperty/analyzerCode: Fail
@@ -167,8 +172,6 @@
 DirectiveAfterDeclaration/part_wrapped_script2: Fail
 DirectiveAfterDeclaration/script1: Fail
 DirectiveAfterDeclaration/script2: Fail
-DuplicateDeferred/example: Fail
-DuplicatePrefix/example: Fail
 DuplicatedDeclarationUse/analyzerCode: Fail # No corresponding analyzer code.
 DuplicatedDeclarationUse/part_wrapped_script1: Fail
 DuplicatedDeclarationUse/part_wrapped_script2: Fail
@@ -176,6 +179,7 @@
 DuplicatedDeclarationUse/script2: Fail # Wrong error.
 DuplicatedDefinition/analyzerCode: Fail
 DuplicatedDefinition/example: Fail
+DuplicateDeferred/example: Fail
 DuplicatedExport/part_wrapped_script: Fail # Exporting file in the (now) part.
 DuplicatedExportInType/analyzerCode: Fail
 DuplicatedExportInType/example: Fail
@@ -187,6 +191,7 @@
 DuplicatedName/example: Fail
 DuplicatedNamedArgument/example: Fail
 DuplicatedParameterName/example: Fail
+DuplicatePrefix/example: Fail
 Encoding/analyzerCode: Fail
 EnumConstantSameNameAsEnclosing/example: Fail
 EnumInstantiation/example: Fail
@@ -266,6 +271,7 @@
 ExternalFactoryWithBody/script1: Fail
 ExternalFieldConstructorInitializer/analyzerCode: Fail
 ExternalFieldInitializer/analyzerCode: Fail
+ExtraneousModifier/part_wrapped_script1: Fail
 ExtraneousModifier/part_wrapped_script10: Fail
 ExtraneousModifier/part_wrapped_script11: Fail
 ExtraneousModifier/part_wrapped_script12: Fail
@@ -274,9 +280,8 @@
 ExtraneousModifier/part_wrapped_script17: Fail
 ExtraneousModifier/part_wrapped_script18: Fail
 ExtraneousModifier/part_wrapped_script19: Fail
-ExtraneousModifier/part_wrapped_script1: Fail
-ExtraneousModifier/part_wrapped_script20: Fail
 ExtraneousModifier/part_wrapped_script2: Fail
+ExtraneousModifier/part_wrapped_script20: Fail
 ExtraneousModifier/part_wrapped_script3: Fail
 ExtraneousModifier/part_wrapped_script4: Fail
 ExtraneousModifier/part_wrapped_script5: Fail
@@ -284,6 +289,7 @@
 ExtraneousModifier/part_wrapped_script7: Fail
 ExtraneousModifier/part_wrapped_script8: Fail
 ExtraneousModifier/part_wrapped_script9: Fail
+ExtraneousModifier/script1: Fail
 ExtraneousModifier/script10: Fail
 ExtraneousModifier/script11: Fail
 ExtraneousModifier/script12: Fail
@@ -292,9 +298,8 @@
 ExtraneousModifier/script17: Fail
 ExtraneousModifier/script18: Fail
 ExtraneousModifier/script19: Fail
-ExtraneousModifier/script1: Fail
-ExtraneousModifier/script20: Fail
 ExtraneousModifier/script2: Fail
+ExtraneousModifier/script20: Fail
 ExtraneousModifier/script3: Fail
 ExtraneousModifier/script4: Fail
 ExtraneousModifier/script5: Fail
@@ -389,10 +394,10 @@
 IncompatibleRedirecteeFunctionType/part_wrapped_script6: Fail
 IncompatibleRedirecteeFunctionType/script6: Fail # Triggers multiple errors.
 IncompatibleRedirecteeFunctionTypeWarning/example: Fail
+IncorrectTypeArgumentInferredWarning/example: Fail
 IncorrectTypeArgumentInReturnTypeWarning/example: Fail
 IncorrectTypeArgumentInSupertypeInferredWarning/example: Fail
 IncorrectTypeArgumentInSupertypeWarning/example: Fail
-IncorrectTypeArgumentInferredWarning/example: Fail
 IncorrectTypeArgumentQualifiedInferredWarning/example: Fail
 IncorrectTypeArgumentQualifiedWarning/example: Fail
 IncorrectTypeArgumentWarning/example: Fail
@@ -438,6 +443,8 @@
 InvalidGetterSetterTypeSetterInheritedGetter/analyzerCode: Fail
 InvalidGetterSetterTypeSetterInheritedGetterLegacy/analyzerCode: Fail
 InvalidInitializer/example: Fail
+InvalidNnbdDillLibrary/analyzerCode: Fail
+InvalidNnbdDillLibrary/example: Fail
 InvalidPackageUri/analyzerCode: Fail
 InvalidPackageUri/example: Fail
 InvalidReturn/analyzerCode: Fail
@@ -549,9 +556,6 @@
 NeverValueWarning/analyzerCode: Fail
 NeverValueWarning/example: Fail
 NoFormals/example: Fail
-NoSuchNamedParameter/example: Fail
-NoUnnamedConstructorInObject/analyzerCode: Fail
-NoUnnamedConstructorInObject/example: Fail
 NonAgnosticConstant/analyzerCode: Fail
 NonAgnosticConstant/example: Fail
 NonAsciiIdentifier/expression: Fail
@@ -559,7 +563,6 @@
 NonConstConstructor/example: Fail
 NonConstFactory/example: Fail
 NonInstanceTypeVariableUse/example: Fail
-NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
 NonNullableInNullAware/analyzerCode: Fail
 NonNullableInNullAware/example: Fail
 NonNullableNotAssignedError/analyzerCode: Fail
@@ -569,14 +572,17 @@
 NonNullableOptOutExplicit/example: Fail
 NonNullableOptOutImplicit/analyzerCode: Fail
 NonNullableOptOutImplicit/example: Fail
+NonNullAwareSpreadIsNull/analyzerCode: Fail # There's no analyzer code for that error yet.
 NonPartOfDirectiveInPart/part_wrapped_script1: Fail
 NonPartOfDirectiveInPart/script1: Fail
+NoSuchNamedParameter/example: Fail
 NotAConstantExpression/example: Fail
-NotAType/example: Fail
 NotAnLvalue/example: Fail
+NotAType/example: Fail
 NotBinaryOperator/analyzerCode: Fail
 NotConstantExpression/example: Fail
-NullAwareCascadeOutOfOrder/example: Fail
+NoUnnamedConstructorInObject/analyzerCode: Fail
+NoUnnamedConstructorInObject/example: Fail
 NullableExpressionCallError/analyzerCode: Fail
 NullableExpressionCallError/example: Fail
 NullableExpressionCallWarning/analyzerCode: Fail
@@ -611,6 +617,7 @@
 NullableTearoffError/example: Fail
 NullableTearoffWarning/analyzerCode: Fail
 NullableTearoffWarning/example: Fail
+NullAwareCascadeOutOfOrder/example: Fail
 OperatorMinusParameterMismatch/example: Fail
 OperatorParameterMismatch0/analyzerCode: Fail
 OperatorParameterMismatch0/example: Fail
@@ -705,15 +712,18 @@
 StrongModeNNBDButOptOut/example: Fail
 StrongModeNNBDPackageOptOut/analyzerCode: Fail
 StrongModeNNBDPackageOptOut/example: Fail
+StrongWithWeakDillLibrary/analyzerCode: Fail
+StrongWithWeakDillLibrary/example: Fail
+StrongWithWeakDillLibrary/spelling: Fail
 SuperAsExpression/example: Fail
 SuperAsIdentifier/example: Fail
-SuperNullAware/example: Fail
 SuperclassHasNoDefaultConstructor/example: Fail
 SuperclassHasNoGetter/example: Fail
 SuperclassHasNoMethod/example: Fail
 SuperclassHasNoSetter/example: Fail
 SuperclassMethodArgumentMismatch/analyzerCode: Fail
 SuperclassMethodArgumentMismatch/example: Fail
+SuperNullAware/example: Fail
 SupertypeIsFunction/analyzerCode: Fail
 SupertypeIsFunction/example: Fail
 SupertypeIsIllegal/example: Fail
@@ -738,14 +748,14 @@
 TypeArgumentMismatch/example: Fail
 TypeArgumentsOnTypeVariable/part_wrapped_script1: Fail
 TypeArgumentsOnTypeVariable/script1: Fail
-TypeNotFound/example: Fail
-TypeVariableDuplicatedName/example: Fail
-TypeVariableSameNameAsEnclosing/example: Fail
 TypedefNotFunction/example: Fail
 TypedefNotType/example: Fail # Feature not yet enabled by default.
 TypedefNullableType/analyzerCode: Fail
 TypedefTypeVariableNotConstructor/analyzerCode: Fail # Feature not yet enabled by default.
 TypedefTypeVariableNotConstructor/example: Fail # Feature not yet enabled by default.
+TypeNotFound/example: Fail
+TypeVariableDuplicatedName/example: Fail
+TypeVariableSameNameAsEnclosing/example: Fail
 UnexpectedToken/part_wrapped_script1: Fail
 UnexpectedToken/script1: Fail
 UnmatchedToken/part_wrapped_script1: Fail
@@ -775,6 +785,8 @@
 ValueForRequiredParameterNotProvidedWarning/example: Fail
 VarAsTypeName/part_wrapped_script1: Fail
 VarAsTypeName/script1: Fail # Too many problems
+WeakWithStrongDillLibrary/analyzerCode: Fail
+WeakWithStrongDillLibrary/example: Fail
 WebLiteralCannotBeRepresentedExactly/analyzerCode: Fail
 WebLiteralCannotBeRepresentedExactly/example: Fail
 YieldAsIdentifier/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index cb15a5f..dea2312 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -1333,6 +1333,21 @@
     Run 'pub outdated --mode=null-safety' to determine if versions of your
     dependencies supporting null safety are available.
 
+WeakWithStrongDillLibrary:
+  template: "Loaded library is compiled with sound null safety and cannot be used in compilation for unsound null safety."
+
+StrongWithWeakDillLibrary:
+  template: "Loaded library is compiled with unsound null safety and cannot be used in compilation for sound null safety."
+
+AgnosticWithStrongDillLibrary:
+  template: "Loaded library is compiled with sound null safety and cannot be used in compilation for agnostic null safety."
+
+AgnosticWithWeakDillLibrary:
+  template: "Loaded library is compiled with unsound null safety and cannot be used in compilation for agnostic null safety."
+
+InvalidNnbdDillLibrary:
+  template: "Trying to use library with invalid null safety."
+
 AbstractNotSync:
   template: "Abstract methods can't use 'async', 'async*', or 'sync*'."
   analyzerCode: NON_SYNC_ABSTRACT_METHOD
diff --git a/pkg/front_end/test/fasta/testing/suite.dart b/pkg/front_end/test/fasta/testing/suite.dart
index 8c4d01e..4ccb3b1 100644
--- a/pkg/front_end/test/fasta/testing/suite.dart
+++ b/pkg/front_end/test/fasta/testing/suite.dart
@@ -83,6 +83,7 @@
         Library,
         Member,
         Node,
+        NonNullableByDefaultCompiledMode,
         TreeNode,
         UnevaluatedConstant,
         Version,
@@ -756,7 +757,19 @@
         } finally {
           await generated.parent.delete(recursive: true);
         }
-        return process.toResult();
+        Result<int> runResult = process.toResult();
+        if (result.component.mode == NonNullableByDefaultCompiledMode.Invalid) {
+          // In this case we expect and want a runtime error.
+          if (runResult.outcome == ExpectationSet.Default["RuntimeError"]) {
+            // We convert this to pass because that's exactly what we'd expect.
+            return pass(0);
+          } else {
+            // Different outcome - that's a failure!
+            return new Result<int>(runResult.output,
+                ExpectationSet.Default["MissingRuntimeError"], runResult.error);
+          }
+        }
+        return runResult;
       case "none":
       case "noneWithJs":
         return pass(0);
diff --git a/pkg/front_end/test/spell_checking_list_messages.txt b/pkg/front_end/test/spell_checking_list_messages.txt
index a0c8cae..324b76d 100644
--- a/pkg/front_end/test/spell_checking_list_messages.txt
+++ b/pkg/front_end/test/spell_checking_list_messages.txt
@@ -62,5 +62,6 @@
 this.x
 type3.#name
 u
+unsound
 v
 x
diff --git a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.outline.expect b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.outline.expect
index 71ff088..a0f941d 100644
--- a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.outline.expect
@@ -10,6 +10,8 @@
 // Run 'pub outdated --mode=null-safety' to determine if versions of your
 // dependencies supporting null safety are available.
 //
+// pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/opt_in_package/lib/opt_in_lib.dart: Error: Loaded library is compiled with unsound null safety and cannot be used in compilation for sound null safety.
+//
 library /*isNonNullableByDefault*/;
 import self as self;
 
diff --git a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.expect b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.expect
index c889df0..d72b9a7 100644
--- a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.expect
@@ -10,6 +10,8 @@
 // Run 'pub outdated --mode=null-safety' to determine if versions of your
 // dependencies supporting null safety are available.
 //
+// pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/opt_in_package/lib/opt_in_lib.dart: Error: Loaded library is compiled with unsound null safety and cannot be used in compilation for sound null safety.
+//
 library /*isNonNullableByDefault*/;
 import self as self;
 
diff --git a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.transformed.expect
index c889df0..d72b9a7 100644
--- a/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/strong.dart.strong.transformed.expect
@@ -10,6 +10,8 @@
 // Run 'pub outdated --mode=null-safety' to determine if versions of your
 // dependencies supporting null safety are available.
 //
+// pkg/front_end/testcases/nnbd/strong_package_not_ok_from_dill/opt_in_package/lib/opt_in_lib.dart: Error: Loaded library is compiled with unsound null safety and cannot be used in compilation for sound null safety.
+//
 library /*isNonNullableByDefault*/;
 import self as self;
 
diff --git a/pkg/front_end/testcases/strong.status b/pkg/front_end/testcases/strong.status
index 452295f..674fd31 100644
--- a/pkg/front_end/testcases/strong.status
+++ b/pkg/front_end/testcases/strong.status
@@ -165,8 +165,6 @@
 inference_new/infer_assign_to_property_custom: TypeCheckError
 inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
 late_lowering/covariant_late_field: TypeCheckError
-late_lowering/initializer_rewrite_from_opt_out: RuntimeError # Test is inherently mixed mode
-late_lowering/non_nullable_from_opt_out: RuntimeError # Test is inherently mixed mode
 nnbd/covariant_late_field: TypeCheckError
 nnbd/getter_vs_setter_type: TypeCheckError
 nnbd/issue41180: RuntimeError # Strong mode runtime checking fails due to mixed strong mode.
@@ -176,8 +174,6 @@
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
-nnbd/strong_lib_not_ok_from_dill/strong: RuntimeError
-nnbd/strong_package_not_ok_from_dill/strong: RuntimeError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 7d1edf3..3605015 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -167,8 +167,6 @@
 inference_new/infer_assign_to_property_custom: TypeCheckError
 inference_new/invalid_assignment_during_toplevel_inference: TypeCheckError
 late_lowering/covariant_late_field: TypeCheckError
-late_lowering/initializer_rewrite_from_opt_out: RuntimeError # Test is inherently mixed mode
-late_lowering/non_nullable_from_opt_out: RuntimeError # Test is inherently mixed mode
 nnbd/covariant_late_field: TypeCheckError
 nnbd/getter_vs_setter_type: TypeCheckError
 nnbd/issue41180: RuntimeError
@@ -178,8 +176,6 @@
 nnbd/nullable_object_access: TypeCheckError
 nnbd/nullable_receiver: TypeCheckError
 nnbd/potentially_nullable_access: TypeCheckError
-nnbd/strong_lib_not_ok_from_dill/strong: RuntimeError
-nnbd/strong_package_not_ok_from_dill/strong: RuntimeError
 rasta/abstract_constructor: RuntimeError
 rasta/bad_constructor_redirection: RuntimeError
 rasta/bad_continue: RuntimeError
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index ec80b02..9928ad2 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -342,7 +342,7 @@
 //                      LIBRARIES and CLASSES
 // ------------------------------------------------------------------------
 
-enum NonNullableByDefaultCompiledMode { Weak, Strong, Agnostic }
+enum NonNullableByDefaultCompiledMode { Weak, Strong, Agnostic, Invalid }
 
 class Library extends NamedNode
     implements Annotatable, Comparable<Library>, FileUriNode {
@@ -393,7 +393,7 @@
     if (!bit1 && !bit2) return NonNullableByDefaultCompiledMode.Weak;
     if (bit1 && !bit2) return NonNullableByDefaultCompiledMode.Strong;
     if (bit1 && bit2) return NonNullableByDefaultCompiledMode.Agnostic;
-    // !bit1 && bit2 is unused.
+    if (!bit1 && bit2) return NonNullableByDefaultCompiledMode.Invalid;
     throw new StateError("Unused bit-pattern for compilation mode");
   }
 
@@ -412,6 +412,10 @@
         flags = (flags | NonNullableByDefaultModeBit1) |
             NonNullableByDefaultModeBit2;
         break;
+      case NonNullableByDefaultCompiledMode.Invalid:
+        flags = (flags & ~NonNullableByDefaultModeBit1) |
+            NonNullableByDefaultModeBit2;
+        break;
     }
   }
 
diff --git a/pkg/kernel/lib/binary/ast_from_binary.dart b/pkg/kernel/lib/binary/ast_from_binary.dart
index 8153e05..6f73e68 100644
--- a/pkg/kernel/lib/binary/ast_from_binary.dart
+++ b/pkg/kernel/lib/binary/ast_from_binary.dart
@@ -2637,6 +2637,15 @@
   if (a == null || a == b) {
     return b;
   }
+
+  // If something is invalid, it should always merge as invalid.
+  if (a == NonNullableByDefaultCompiledMode.Invalid) {
+    return a;
+  }
+  if (b == NonNullableByDefaultCompiledMode.Invalid) {
+    return b;
+  }
+
   if (a == NonNullableByDefaultCompiledMode.Agnostic) {
     return b;
   }
diff --git a/runtime/vm/compiler/frontend/kernel_translation_helper.h b/runtime/vm/compiler/frontend/kernel_translation_helper.h
index 4dfed5a..ed347e5 100644
--- a/runtime/vm/compiler/frontend/kernel_translation_helper.h
+++ b/runtime/vm/compiler/frontend/kernel_translation_helper.h
@@ -793,7 +793,7 @@
     if (!bit1 && !bit2) return NNBDCompiledMode::kWeak;
     if (bit1 && !bit2) return NNBDCompiledMode::kStrong;
     if (bit1 && bit2) return NNBDCompiledMode::kAgnostic;
-    // !bit1 && bit2 is unused.
+    if (!bit1 && bit2) return NNBDCompiledMode::kInvalid;
     UNREACHABLE();
   }
 
diff --git a/runtime/vm/kernel_loader.cc b/runtime/vm/kernel_loader.cc
index e3860d0..4f977cc 100644
--- a/runtime/vm/kernel_loader.cc
+++ b/runtime/vm/kernel_loader.cc
@@ -1013,6 +1013,12 @@
   library.set_is_nnbd(library_helper.IsNonNullableByDefault());
   const NNBDCompiledMode mode =
       library_helper.GetNonNullableByDefaultCompiledMode();
+  if (mode == NNBDCompiledMode::kInvalid) {
+    H.ReportError(
+        "Library '%s' was compiled in an unsupported mixed mode between sound "
+        "null safety and not sound null safety.",
+        String::Handle(library.url()).ToCString());
+  }
   if (!I->null_safety() && mode == NNBDCompiledMode::kStrong) {
     H.ReportError(
         "Library '%s' was compiled with sound null safety (in strong mode) and "
diff --git a/runtime/vm/object.h b/runtime/vm/object.h
index 28e2443..bb0b642 100644
--- a/runtime/vm/object.h
+++ b/runtime/vm/object.h
@@ -914,6 +914,7 @@
   kWeak = 0,
   kStrong = 1,
   kAgnostic = 2,
+  kInvalid = 3,
 };
 
 class Class : public Object {