[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 {