[cfe] Remove unnecesary uses of SubtypeCheckMode.ignoreNullabilities
Change-Id: I8b64ca39e7a153141885d428fc5bd95e446fcb49
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/135640
Commit-Queue: Dmitry Stefantsov <dmitryas@google.com>
Reviewed-by: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/class_builder.dart b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
index 3668b87..9a160af 100644
--- a/pkg/front_end/lib/src/fasta/builder/class_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/class_builder.dart
@@ -67,6 +67,8 @@
import '../kernel/types.dart' show Types;
+import '../loader.dart';
+
import '../modifier.dart';
import '../names.dart' show noSuchMethodName;
@@ -77,6 +79,8 @@
import '../source/source_library_builder.dart' show SourceLibraryBuilder;
+import '../source/source_loader.dart';
+
import '../type_inference/type_schema.dart' show UnknownType;
import 'builder.dart';
@@ -688,50 +692,84 @@
Supertype supertype, TypeEnvironment typeEnvironment) {
SourceLibraryBuilder library = this.library;
- List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- new InterfaceType(
- supertype.classNode, library.nonNullable, supertype.typeArguments),
- typeEnvironment,
- allowSuperBounded: false);
- if (issues != null) {
- for (TypeArgumentIssue issue in issues) {
- Message message;
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssues(
+ new InterfaceType(supertype.classNode, library.nonNullable,
+ supertype.typeArguments),
+ typeEnvironment,
+ SubtypeCheckMode.ignoringNullabilities,
+ allowSuperBounded: false)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ library.isNonNullableByDefault && library.loader.performNnbdChecks
+ ? findTypeArgumentIssues(
+ new InterfaceType(supertype.classNode, library.nonNullable,
+ supertype.typeArguments),
+ typeEnvironment,
+ SubtypeCheckMode.withNullabilities,
+ allowSuperBounded: false)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null || nnbdIssues != null) {
+ Set<TypeArgumentIssue> mergedIssues = legacyIssues ?? {};
+ if (nnbdIssues != null) {
+ mergedIssues.addAll(nnbdIssues.where(
+ (issue) => legacyIssues == null || !legacyIssues.contains(issue)));
+ }
+ for (TypeArgumentIssue issue in mergedIssues) {
DartType argument = issue.argument;
TypeParameter typeParameter = issue.typeParameter;
bool inferred = library.inferredTypes.contains(argument);
if (argument is FunctionType && argument.typeParameters.length > 0) {
if (inferred) {
- message = templateGenericFunctionTypeInferredAsActualTypeArgument
- .withArguments(argument, library.isNonNullableByDefault);
+ library.reportTypeArgumentIssue(
+ templateGenericFunctionTypeInferredAsActualTypeArgument
+ .withArguments(argument, library.isNonNullableByDefault),
+ fileUri,
+ charOffset,
+ null);
} else {
- message = messageGenericFunctionTypeUsedAsActualTypeArgument;
+ library.reportTypeArgumentIssue(
+ messageGenericFunctionTypeUsedAsActualTypeArgument,
+ fileUri,
+ charOffset,
+ null);
}
- typeParameter = null;
} else {
- if (inferred) {
- message =
- templateIncorrectTypeArgumentInSupertypeInferred.withArguments(
+ void reportProblem(
+ Template<
+ Message Function(DartType, DartType, String, String,
+ String, String, bool)>
+ template) {
+ library.reportTypeArgumentIssue(
+ template.withArguments(
argument,
typeParameter.bound,
typeParameter.name,
getGenericTypeName(issue.enclosingType),
supertype.classNode.name,
name,
- library.isNonNullableByDefault);
+ library.isNonNullableByDefault),
+ fileUri,
+ charOffset,
+ typeParameter);
+ }
+
+ nnbdIssues ??= const {};
+ if (inferred) {
+ if (nnbdIssues.contains(issue) && !library.loader.nnbdStrongMode) {
+ reportProblem(
+ templateIncorrectTypeArgumentInSupertypeInferredWarning);
+ } else {
+ reportProblem(templateIncorrectTypeArgumentInSupertypeInferred);
+ }
} else {
- message = templateIncorrectTypeArgumentInSupertype.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- getGenericTypeName(issue.enclosingType),
- supertype.classNode.name,
- name,
- library.isNonNullableByDefault);
+ if (nnbdIssues.contains(issue) && !library.loader.nnbdStrongMode) {
+ reportProblem(templateIncorrectTypeArgumentInSupertypeWarning);
+ } else {
+ reportProblem(templateIncorrectTypeArgumentInSupertype);
+ }
}
}
-
- library.reportTypeArgumentIssue(
- message, fileUri, charOffset, typeParameter);
}
}
}
@@ -742,11 +780,26 @@
// Check in bounds of own type variables.
for (TypeParameter parameter in cls.typeParameters) {
- List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- parameter.bound, typeEnvironment,
- allowSuperBounded: true);
- if (issues != null) {
- for (TypeArgumentIssue issue in issues) {
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssues(
+ parameter.bound,
+ typeEnvironment,
+ SubtypeCheckMode.ignoringNullabilities,
+ allowSuperBounded: true)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ library.isNonNullableByDefault && library.loader.performNnbdChecks
+ ? findTypeArgumentIssues(parameter.bound, typeEnvironment,
+ SubtypeCheckMode.withNullabilities,
+ allowSuperBounded: true)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null || nnbdIssues != null) {
+ Set<TypeArgumentIssue> mergedIssues = legacyIssues ?? {};
+ if (nnbdIssues != null) {
+ mergedIssues.addAll(nnbdIssues.where((issue) =>
+ legacyIssues == null || !legacyIssues.contains(issue)));
+ }
+ for (TypeArgumentIssue issue in mergedIssues) {
DartType argument = issue.argument;
TypeParameter typeParameter = issue.typeParameter;
if (library.inferredTypes.contains(argument)) {
@@ -758,21 +811,37 @@
continue;
}
- Message message;
if (argument is FunctionType && argument.typeParameters.length > 0) {
- message = messageGenericFunctionTypeUsedAsActualTypeArgument;
- typeParameter = null;
+ library.reportTypeArgumentIssue(
+ messageGenericFunctionTypeUsedAsActualTypeArgument,
+ fileUri,
+ parameter.fileOffset,
+ null);
} else {
- message = templateIncorrectTypeArgument.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- getGenericTypeName(issue.enclosingType),
- library.isNonNullableByDefault);
- }
+ void reportProblem(
+ Template<
+ Message Function(
+ DartType, DartType, String, String, bool)>
+ template) {
+ library.reportTypeArgumentIssue(
+ template.withArguments(
+ argument,
+ typeParameter.bound,
+ typeParameter.name,
+ getGenericTypeName(issue.enclosingType),
+ library.isNonNullableByDefault),
+ fileUri,
+ parameter.fileOffset,
+ typeParameter);
+ }
- library.reportTypeArgumentIssue(
- message, fileUri, parameter.fileOffset, typeParameter);
+ nnbdIssues ??= const {};
+ if (nnbdIssues.contains(issue) && !library.loader.nnbdStrongMode) {
+ reportProblem(templateIncorrectTypeArgumentWarning);
+ } else {
+ reportProblem(templateIncorrectTypeArgument);
+ }
+ }
}
}
}
@@ -1178,11 +1247,11 @@
DartType supertype = inParameter ? declaredType : interfaceType;
if (types.isSubtypeOfKernel(
- subtype, supertype, SubtypeCheckMode.ignoringNullabilities)) {
+ subtype, supertype, SubtypeCheckMode.withNullabilities)) {
// No problem--the proper subtyping relation is satisfied.
} else if (isCovariant &&
types.isSubtypeOfKernel(
- supertype, subtype, SubtypeCheckMode.ignoringNullabilities)) {
+ supertype, subtype, SubtypeCheckMode.withNullabilities)) {
// No problem--the overriding parameter is marked "covariant" and has
// a type which is a subtype of the parameter it overrides.
} else if (subtype is InvalidType || supertype is InvalidType) {
@@ -1190,48 +1259,82 @@
// been reported.
} else {
// Report an error.
- String declaredMemberName =
- '${declaredMember.enclosingClass.name}.${declaredMember.name.name}';
- String interfaceMemberName =
- '${interfaceMember.enclosingClass.name}.${interfaceMember.name.name}';
- Message message;
- int fileOffset;
- if (declaredParameter == null) {
- if (asIfDeclaredParameter) {
- // Setter overridden by field
- message = templateOverrideTypeMismatchSetter.withArguments(
- declaredMemberName,
- declaredType,
- interfaceType,
- interfaceMemberName,
- library.isNonNullableByDefault);
+ bool isErrorInNnbdOptedOutMode = !types.isSubtypeOfKernel(
+ subtype, supertype, SubtypeCheckMode.ignoringNullabilities) &&
+ (!isCovariant ||
+ !types.isSubtypeOfKernel(
+ supertype, subtype, SubtypeCheckMode.ignoringNullabilities));
+ Loader loader = library.loader;
+ bool performNnbdChecks = loader is SourceLoader &&
+ library.isNonNullableByDefault &&
+ loader.performNnbdChecks;
+ bool nnbdStrongMode = loader is SourceLoader && loader.nnbdStrongMode;
+ bool isError =
+ isErrorInNnbdOptedOutMode || performNnbdChecks && nnbdStrongMode;
+ bool isWarning =
+ !isErrorInNnbdOptedOutMode && performNnbdChecks && !nnbdStrongMode;
+ assert(
+ !isError || !isWarning,
+ "A compile-time problem can't be an error and a warning "
+ "at the same time.");
+ if (isError || isWarning) {
+ String declaredMemberName = '${declaredMember.enclosingClass.name}'
+ '.${declaredMember.name.name}';
+ String interfaceMemberName = '${interfaceMember.enclosingClass.name}'
+ '.${interfaceMember.name.name}';
+ Message message;
+ int fileOffset;
+ if (declaredParameter == null) {
+ if (asIfDeclaredParameter) {
+ // Setter overridden by field
+ Template<Message Function(String, DartType, DartType, String, bool)>
+ template = isError
+ ? templateOverrideTypeMismatchSetter
+ : templateOverrideTypeMismatchSetterWarning;
+ message = template.withArguments(
+ declaredMemberName,
+ declaredType,
+ interfaceType,
+ interfaceMemberName,
+ library.isNonNullableByDefault);
+ } else {
+ Template<Message Function(String, DartType, DartType, String, bool)>
+ template = isError
+ ? templateOverrideTypeMismatchReturnType
+ : templateOverrideTypeMismatchReturnTypeWarning;
+ message = template.withArguments(
+ declaredMemberName,
+ declaredType,
+ interfaceType,
+ interfaceMemberName,
+ library.isNonNullableByDefault);
+ }
+ fileOffset = declaredMember.fileOffset;
} else {
- message = templateOverrideTypeMismatchReturnType.withArguments(
+ Template<
+ Message Function(
+ String, String, DartType, DartType, String, bool)>
+ template = isError
+ ? templateOverrideTypeMismatchParameter
+ : templateOverrideTypeMismatchParameterWarning;
+ message = template.withArguments(
+ declaredParameter.name,
declaredMemberName,
declaredType,
interfaceType,
interfaceMemberName,
library.isNonNullableByDefault);
+ fileOffset = declaredParameter.fileOffset;
}
- fileOffset = declaredMember.fileOffset;
- } else {
- message = templateOverrideTypeMismatchParameter.withArguments(
- declaredParameter.name,
- declaredMemberName,
- declaredType,
- interfaceType,
- interfaceMemberName,
- library.isNonNullableByDefault);
- fileOffset = declaredParameter.fileOffset;
+ reportInvalidOverride(
+ isInterfaceCheck, declaredMember, message, fileOffset, noLength,
+ context: [
+ templateOverriddenMethodCause
+ .withArguments(interfaceMember.name.name)
+ .withLocation(_getMemberUri(interfaceMember),
+ interfaceMember.fileOffset, noLength)
+ ]);
}
- reportInvalidOverride(
- isInterfaceCheck, declaredMember, message, fileOffset, noLength,
- context: [
- templateOverriddenMethodCause
- .withArguments(interfaceMember.name.name)
- .withLocation(_getMemberUri(interfaceMember),
- interfaceMember.fileOffset, noLength)
- ]);
}
}
@@ -1652,6 +1755,7 @@
DartType typeArgument = typeArguments[i];
// Check whether the [typeArgument] respects the bounds of
// [typeParameter].
+ Loader loader = library.loader;
if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
SubtypeCheckMode.ignoringNullabilities)) {
addProblem(
@@ -1662,6 +1766,29 @@
redirectionTarget.charOffset,
noLength);
hasProblem = true;
+ } else if (library.isNonNullableByDefault &&
+ loader is SourceLoader &&
+ loader.performNnbdChecks) {
+ if (!typeEnvironment.isSubtypeOf(typeArgument, typeParameterBound,
+ SubtypeCheckMode.withNullabilities)) {
+ if (loader.nnbdStrongMode) {
+ addProblem(
+ templateRedirectingFactoryIncompatibleTypeArgument
+ .withArguments(typeArgument, typeParameterBound,
+ library.isNonNullableByDefault),
+ redirectionTarget.charOffset,
+ noLength);
+ hasProblem = true;
+ } else {
+ addProblem(
+ templateRedirectingFactoryIncompatibleTypeArgumentWarning
+ .withArguments(typeArgument, typeParameterBound,
+ library.isNonNullableByDefault),
+ redirectionTarget.charOffset,
+ noLength);
+ hasProblem = false;
+ }
+ }
}
}
} else if (typeArguments == null &&
@@ -1716,6 +1843,7 @@
if (redirecteeType == null) return;
// Check whether [redirecteeType] <: [factoryType].
+ Loader loader = library.loader;
if (!typeEnvironment.isSubtypeOf(
redirecteeType, factoryType, SubtypeCheckMode.ignoringNullabilities)) {
addProblem(
@@ -1723,6 +1851,25 @@
redirecteeType, factoryType, library.isNonNullableByDefault),
factory.redirectionTarget.charOffset,
noLength);
+ } else if (library.isNonNullableByDefault &&
+ loader is SourceLoader &&
+ loader.performNnbdChecks) {
+ if (!typeEnvironment.isSubtypeOf(
+ redirecteeType, factoryType, SubtypeCheckMode.withNullabilities)) {
+ if (loader.nnbdStrongMode) {
+ addProblem(
+ templateIncompatibleRedirecteeFunctionType.withArguments(
+ redirecteeType, factoryType, library.isNonNullableByDefault),
+ factory.redirectionTarget.charOffset,
+ noLength);
+ } else {
+ addProblem(
+ templateIncompatibleRedirecteeFunctionTypeWarning.withArguments(
+ redirecteeType, factoryType, library.isNonNullableByDefault),
+ factory.redirectionTarget.charOffset,
+ noLength);
+ }
+ }
}
}
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
index 8085b94..c28169c 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_cfe_generated.dart
@@ -1053,6 +1053,44 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>
+ templateIncompatibleRedirecteeFunctionTypeWarning = const Template<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""The constructor function type '#type' isn't a subtype of '#type2'.""",
+ withArguments: _withArgumentsIncompatibleRedirecteeFunctionTypeWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>
+ codeIncompatibleRedirecteeFunctionTypeWarning = const Code<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>(
+ "IncompatibleRedirecteeFunctionTypeWarning",
+ templateIncompatibleRedirecteeFunctionTypeWarning,
+ analyzerCodes: <String>["REDIRECT_TO_INVALID_TYPE"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncompatibleRedirecteeFunctionTypeWarning(
+ DartType _type, DartType _type2, bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncompatibleRedirecteeFunctionTypeWarning,
+ message:
+ """The constructor function type '${type}' isn't a subtype of '${type2}'.""" +
+ labeler.originMessages,
+ arguments: {'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(DartType _type, DartType _type2, String name,
String name2, bool isNonNullableByDefault)>
templateIncorrectTypeArgument = const Template<
@@ -1150,6 +1188,56 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentInReturnTypeWarning = const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the return type.""",
+ tipTemplate:
+ r"""Try changing type arguments so that they conform to the bounds.""",
+ withArguments: _withArgumentsIncorrectTypeArgumentInReturnTypeWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentInReturnTypeWarning = const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentInReturnTypeWarning",
+ templateIncorrectTypeArgumentInReturnTypeWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentInReturnTypeWarning(DartType _type,
+ DartType _type2, String name, String name2, bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncorrectTypeArgumentInReturnTypeWarning,
+ message:
+ """Type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${name2}' in the return type.""" +
+ labeler.originMessages,
+ tip: """Try changing type arguments so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(
DartType _type,
DartType _type2,
@@ -1320,6 +1408,181 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentInSupertypeInferredWarning = const Template<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'.""",
+ tipTemplate:
+ r"""Try specifying type arguments explicitly so that they conform to the bounds.""",
+ withArguments:
+ _withArgumentsIncorrectTypeArgumentInSupertypeInferredWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentInSupertypeInferredWarning = const Code<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentInSupertypeInferredWarning",
+ templateIncorrectTypeArgumentInSupertypeInferredWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentInSupertypeInferredWarning(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ if (name3.isEmpty) throw 'No name provided';
+ name3 = demangleMixinApplicationName(name3);
+ if (name4.isEmpty) throw 'No name provided';
+ name4 = demangleMixinApplicationName(name4);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncorrectTypeArgumentInSupertypeInferredWarning,
+ message:
+ """Inferred type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${name2}' in the supertype '${name3}' of class '${name4}'.""" +
+ labeler.originMessages,
+ tip:
+ """Try specifying type arguments explicitly so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'name2': name2,
+ 'name3': name3,
+ 'name4': name4
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentInSupertypeWarning = const Template<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'.""",
+ tipTemplate:
+ r"""Try changing type arguments so that they conform to the bounds.""",
+ withArguments: _withArgumentsIncorrectTypeArgumentInSupertypeWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentInSupertypeWarning = const Code<
+ Message Function(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentInSupertypeWarning",
+ templateIncorrectTypeArgumentInSupertypeWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentInSupertypeWarning(
+ DartType _type,
+ DartType _type2,
+ String name,
+ String name2,
+ String name3,
+ String name4,
+ bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ if (name3.isEmpty) throw 'No name provided';
+ name3 = demangleMixinApplicationName(name3);
+ if (name4.isEmpty) throw 'No name provided';
+ name4 = demangleMixinApplicationName(name4);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncorrectTypeArgumentInSupertypeWarning,
+ message:
+ """Type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${name2}' in the supertype '${name3}' of class '${name4}'.""" +
+ labeler.originMessages,
+ tip:
+ """Try changing type arguments so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'name2': name2,
+ 'name3': name3,
+ 'name4': name4
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(DartType _type, DartType _type2, String name,
String name2, bool isNonNullableByDefault)>
templateIncorrectTypeArgumentInferred = const Template<
@@ -1369,6 +1632,56 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentInferredWarning = const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2'.""",
+ tipTemplate:
+ r"""Try specifying type arguments explicitly so that they conform to the bounds.""",
+ withArguments: _withArgumentsIncorrectTypeArgumentInferredWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentInferredWarning = const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentInferredWarning",
+ templateIncorrectTypeArgumentInferredWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentInferredWarning(DartType _type,
+ DartType _type2, String name, String name2, bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncorrectTypeArgumentInferredWarning,
+ message:
+ """Inferred type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${name2}'.""" +
+ labeler.originMessages,
+ tip: """Try specifying type arguments explicitly so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(DartType _type, DartType _type2, String name,
DartType _type3, String name2, bool isNonNullableByDefault)>
templateIncorrectTypeArgumentQualified = const Template<
Message Function(DartType _type, DartType _type2, String name,
@@ -1481,6 +1794,172 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentQualifiedInferredWarning = const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'.""",
+ tipTemplate:
+ r"""Try specifying type arguments explicitly so that they conform to the bounds.""",
+ withArguments:
+ _withArgumentsIncorrectTypeArgumentQualifiedInferredWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentQualifiedInferredWarning = const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentQualifiedInferredWarning",
+ templateIncorrectTypeArgumentQualifiedInferredWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentQualifiedInferredWarning(
+ DartType _type,
+ DartType _type2,
+ String name,
+ DartType _type3,
+ String name2,
+ bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ List<Object> type3Parts = labeler.labelType(_type3);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ String type3 = type3Parts.join();
+ return new Message(codeIncorrectTypeArgumentQualifiedInferredWarning,
+ message:
+ """Inferred type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${type3}.${name2}'.""" +
+ labeler.originMessages,
+ tip: """Try specifying type arguments explicitly so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'type3': _type3,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentQualifiedWarning = const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'.""",
+ tipTemplate:
+ r"""Try changing type arguments so that they conform to the bounds.""",
+ withArguments: _withArgumentsIncorrectTypeArgumentQualifiedWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentQualifiedWarning = const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ DartType _type3, String name2, bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentQualifiedWarning",
+ templateIncorrectTypeArgumentQualifiedWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentQualifiedWarning(
+ DartType _type,
+ DartType _type2,
+ String name,
+ DartType _type3,
+ String name2,
+ bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ List<Object> type3Parts = labeler.labelType(_type3);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ String type3 = type3Parts.join();
+ return new Message(codeIncorrectTypeArgumentQualifiedWarning,
+ message:
+ """Type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${type3}.${name2}'.""" +
+ labeler.originMessages,
+ tip: """Try changing type arguments so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'type3': _type3,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ templateIncorrectTypeArgumentWarning = const Template<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2'.""",
+ tipTemplate:
+ r"""Try changing type arguments so that they conform to the bounds.""",
+ withArguments: _withArgumentsIncorrectTypeArgumentWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>
+ codeIncorrectTypeArgumentWarning = const Code<
+ Message Function(DartType _type, DartType _type2, String name,
+ String name2, bool isNonNullableByDefault)>(
+ "IncorrectTypeArgumentWarning", templateIncorrectTypeArgumentWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsIncorrectTypeArgumentWarning(DartType _type,
+ DartType _type2, String name, String name2, bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeIncorrectTypeArgumentWarning,
+ message:
+ """Type argument '${type}' doesn't conform to the bound '${type2}' of the type variable '${name}' on '${name2}'.""" +
+ labeler.originMessages,
+ tip: """Try changing type arguments so that they conform to the bounds.""",
+ arguments: {
+ 'type': _type,
+ 'type2': _type2,
+ 'name': name,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(String name, DartType _type, DartType _type2,
bool isNonNullableByDefault)>
templateInitializingFormalTypeMismatch = const Template<
@@ -2503,6 +2982,64 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(String name, String name2, DartType _type,
+ DartType _type2, String name3, bool isNonNullableByDefault)>
+ templateOverrideTypeMismatchParameterWarning = const Template<
+ Message Function(String name, String name2, DartType _type,
+ DartType _type2, String name3, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""The parameter '#name' of the method '#name2' has type '#type', which does not match the corresponding type, '#type2', in the overridden method, '#name3'.""",
+ tipTemplate:
+ r"""Change to a supertype of '#type2', or, for a covariant parameter, a subtype.""",
+ withArguments: _withArgumentsOverrideTypeMismatchParameterWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(String name, String name2, DartType _type,
+ DartType _type2, String name3, bool isNonNullableByDefault)>
+ codeOverrideTypeMismatchParameterWarning = const Code<
+ Message Function(String name, String name2, DartType _type,
+ DartType _type2, String name3, bool isNonNullableByDefault)>(
+ "OverrideTypeMismatchParameterWarning",
+ templateOverrideTypeMismatchParameterWarning,
+ analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOverrideTypeMismatchParameterWarning(
+ String name,
+ String name2,
+ DartType _type,
+ DartType _type2,
+ String name3,
+ bool isNonNullableByDefault) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name3.isEmpty) throw 'No name provided';
+ name3 = demangleMixinApplicationName(name3);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeOverrideTypeMismatchParameterWarning,
+ message:
+ """The parameter '${name}' of the method '${name2}' has type '${type}', which does not match the corresponding type, '${type2}', in the overridden method, '${name3}'.""" +
+ labeler.originMessages,
+ tip: """Change to a supertype of '${type2}', or, for a covariant parameter, a subtype.""",
+ arguments: {
+ 'name': name,
+ 'name2': name2,
+ 'type': _type,
+ 'type2': _type2,
+ 'name3': name3
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(String name, DartType _type, DartType _type2,
String name2, bool isNonNullableByDefault)>
templateOverrideTypeMismatchReturnType = const Template<
@@ -2557,6 +3094,59 @@
const Template<
Message Function(String name, DartType _type, DartType _type2,
String name2, bool isNonNullableByDefault)>
+ templateOverrideTypeMismatchReturnTypeWarning = const Template<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""The return type of the method '#name' is '#type', which does not match the return type, '#type2', of the overridden method, '#name2'.""",
+ tipTemplate: r"""Change to a subtype of '#type2'.""",
+ withArguments: _withArgumentsOverrideTypeMismatchReturnTypeWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>
+ codeOverrideTypeMismatchReturnTypeWarning = const Code<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>(
+ "OverrideTypeMismatchReturnTypeWarning",
+ templateOverrideTypeMismatchReturnTypeWarning,
+ analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOverrideTypeMismatchReturnTypeWarning(
+ String name,
+ DartType _type,
+ DartType _type2,
+ String name2,
+ bool isNonNullableByDefault) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeOverrideTypeMismatchReturnTypeWarning,
+ message:
+ """The return type of the method '${name}' is '${type}', which does not match the return type, '${type2}', of the overridden method, '${name2}'.""" +
+ labeler.originMessages,
+ tip: """Change to a subtype of '${type2}'.""",
+ arguments: {
+ 'name': name,
+ 'type': _type,
+ 'type2': _type2,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>
templateOverrideTypeMismatchSetter = const Template<
Message Function(String name, DartType _type, DartType _type2,
String name2, bool isNonNullableByDefault)>(
@@ -2600,6 +3190,57 @@
// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
const Template<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>
+ templateOverrideTypeMismatchSetterWarning = const Template<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>(
+ messageTemplate:
+ r"""The field '#name' has type '#type', which does not match the corresponding type, '#type2', in the overridden setter, '#name2'.""",
+ withArguments: _withArgumentsOverrideTypeMismatchSetterWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>
+ codeOverrideTypeMismatchSetterWarning = const Code<
+ Message Function(String name, DartType _type, DartType _type2,
+ String name2, bool isNonNullableByDefault)>(
+ "OverrideTypeMismatchSetterWarning",
+ templateOverrideTypeMismatchSetterWarning,
+ analyzerCodes: <String>["INVALID_METHOD_OVERRIDE"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsOverrideTypeMismatchSetterWarning(
+ String name,
+ DartType _type,
+ DartType _type2,
+ String name2,
+ bool isNonNullableByDefault) {
+ if (name.isEmpty) throw 'No name provided';
+ name = demangleMixinApplicationName(name);
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ if (name2.isEmpty) throw 'No name provided';
+ name2 = demangleMixinApplicationName(name2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeOverrideTypeMismatchSetterWarning,
+ message:
+ """The field '${name}' has type '${type}', which does not match the corresponding type, '${type2}', in the overridden setter, '${name2}'.""" +
+ labeler.originMessages,
+ arguments: {
+ 'name': name,
+ 'type': _type,
+ 'type2': _type2,
+ 'name2': name2
+ });
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
Message Function(DartType _type, String name, String name2,
DartType _type2, String name3, bool isNonNullableByDefault)>
templateOverrideTypeVariablesBoundMismatch = const Template<
@@ -2694,6 +3335,45 @@
const Template<
Message Function(
DartType _type, DartType _type2, bool isNonNullableByDefault)>
+ templateRedirectingFactoryIncompatibleTypeArgumentWarning = const Template<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>(
+ messageTemplate: r"""The type '#type' doesn't extend '#type2'.""",
+ tipTemplate: r"""Try using a different type as argument.""",
+ withArguments:
+ _withArgumentsRedirectingFactoryIncompatibleTypeArgumentWarning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Code<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>
+ codeRedirectingFactoryIncompatibleTypeArgumentWarning = const Code<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>(
+ "RedirectingFactoryIncompatibleTypeArgumentWarning",
+ templateRedirectingFactoryIncompatibleTypeArgumentWarning,
+ analyzerCodes: <String>["TYPE_ARGUMENT_NOT_MATCHING_BOUNDS"],
+ severity: Severity.warning);
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+Message _withArgumentsRedirectingFactoryIncompatibleTypeArgumentWarning(
+ DartType _type, DartType _type2, bool isNonNullableByDefault) {
+ TypeLabeler labeler = new TypeLabeler(isNonNullableByDefault);
+ List<Object> typeParts = labeler.labelType(_type);
+ List<Object> type2Parts = labeler.labelType(_type2);
+ String type = typeParts.join();
+ String type2 = type2Parts.join();
+ return new Message(codeRedirectingFactoryIncompatibleTypeArgumentWarning,
+ message: """The type '${type}' doesn't extend '${type2}'.""" +
+ labeler.originMessages,
+ tip: """Try using a different type as argument.""",
+ arguments: {'type': _type, 'type2': _type2});
+}
+
+// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
+const Template<
+ Message Function(
+ DartType _type, DartType _type2, bool isNonNullableByDefault)>
templateSpreadElementTypeMismatch = const Template<
Message Function(
DartType _type, DartType _type2, bool isNonNullableByDefault)>(
diff --git a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
index 526fdce..ace9ea1 100644
--- a/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/body_builder.dart
@@ -1030,8 +1030,8 @@
switch (asyncModifier) {
case AsyncMarker.Async:
DartType futureBottomType = libraryBuilder.loader.futureOfBottom;
- if (!typeEnvironment.isSubtypeOf(futureBottomType, returnType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ if (!typeEnvironment.isSubtypeOf(
+ futureBottomType, returnType, SubtypeCheckMode.withNullabilities)) {
problem = fasta.messageIllegalAsyncReturnType;
}
break;
@@ -1040,8 +1040,8 @@
DartType streamBottomType = libraryBuilder.loader.streamOfBottom;
if (returnType is VoidType) {
problem = fasta.messageIllegalAsyncGeneratorVoidReturnType;
- } else if (!typeEnvironment.isSubtypeOf(streamBottomType, returnType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ } else if (!typeEnvironment.isSubtypeOf(
+ streamBottomType, returnType, SubtypeCheckMode.withNullabilities)) {
problem = fasta.messageIllegalAsyncGeneratorReturnType;
}
break;
@@ -1051,7 +1051,7 @@
if (returnType is VoidType) {
problem = fasta.messageIllegalSyncGeneratorVoidReturnType;
} else if (!typeEnvironment.isSubtypeOf(iterableBottomType, returnType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ SubtypeCheckMode.withNullabilities)) {
problem = fasta.messageIllegalSyncGeneratorReturnType;
}
break;
@@ -5560,7 +5560,7 @@
if (formal != null && formal.type != null) {
DartType formalType = formal.variable.type;
if (!typeEnvironment.isSubtypeOf(formalType, builder.fieldType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ SubtypeCheckMode.withNullabilities)) {
libraryBuilder.addProblem(
fasta.templateInitializingFormalTypeMismatch.withArguments(
name,
diff --git a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
index 874406a..fb3b432 100644
--- a/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/class_hierarchy_builder.dart
@@ -2348,8 +2348,12 @@
if (a.hadTypesInferred) {
if (b.isSetter &&
(!a.isAssignable ||
- hierarchy.types.isSubtypeOfKernel(type, a.fieldType,
- SubtypeCheckMode.ignoringNullabilities))) {
+ hierarchy.types.isSubtypeOfKernel(
+ type,
+ a.fieldType,
+ classBuilder.library.isNonNullableByDefault
+ ? SubtypeCheckMode.withNullabilities
+ : SubtypeCheckMode.ignoringNullabilities))) {
type = a.fieldType;
} else {
reportCantInferFieldType(classBuilder, a);
@@ -2636,10 +2640,10 @@
bool isMoreSpecific(ClassHierarchyBuilder hierarchy, DartType a, DartType b) {
if (isSetter) {
return hierarchy.types
- .isSubtypeOfKernel(b, a, SubtypeCheckMode.ignoringNullabilities);
+ .isSubtypeOfKernel(b, a, SubtypeCheckMode.withNullabilities);
} else {
return hierarchy.types
- .isSubtypeOfKernel(a, b, SubtypeCheckMode.ignoringNullabilities);
+ .isSubtypeOfKernel(a, b, SubtypeCheckMode.withNullabilities);
}
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
index 645e2b95..430c3df 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -1983,7 +1983,7 @@
}
}
return typeEnvironment.isSubtypeOf(
- constantType, type, SubtypeCheckMode.ignoringNullabilities);
+ constantType, type, SubtypeCheckMode.withNullabilities);
}
Constant ensureIsSubtype(Constant constant, DartType type, TreeNode node) {
diff --git a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
index e2b7695..64cb9c8 100644
--- a/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/inference_visitor.dart
@@ -1791,11 +1791,11 @@
bool isMap = inferrer.typeSchemaEnvironment.isSubtypeOf(
spreadType,
inferrer.coreTypes.mapRawType(inferrer.library.nullable),
- SubtypeCheckMode.ignoringNullabilities);
+ SubtypeCheckMode.withNullabilities);
bool isIterable = inferrer.typeSchemaEnvironment.isSubtypeOf(
spreadType,
inferrer.coreTypes.iterableRawType(inferrer.library.nullable),
- SubtypeCheckMode.ignoringNullabilities);
+ SubtypeCheckMode.withNullabilities);
if (isMap && !isIterable) {
mapSpreadOffset = entry.fileOffset;
}
diff --git a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
index c35373e..d5a37ef 100644
--- a/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/transform_collections.dart
@@ -257,7 +257,7 @@
Statement loopBody;
if (element.elementType == null ||
!typeEnvironment.isSubtypeOf(element.elementType, elementType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ SubtypeCheckMode.withNullabilities)) {
variable = _createForInVariable(element.fileOffset, const DynamicType());
VariableDeclaration castedVar = _createVariable(
_createImplicitAs(element.expression.fileOffset,
@@ -441,8 +441,8 @@
VariableDeclaration variable;
Statement loopBody;
if (entry.entryType == null ||
- !typeEnvironment.isSubtypeOf(entry.entryType, entryType,
- SubtypeCheckMode.ignoringNullabilities)) {
+ !typeEnvironment.isSubtypeOf(
+ entry.entryType, entryType, SubtypeCheckMode.withNullabilities)) {
variable = _createForInVariable(
entry.fileOffset,
new InterfaceType(mapEntryClass, _currentLibrary.nonNullable,
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 8cd6381..ace7e55 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
@@ -67,7 +67,8 @@
import 'package:kernel/type_algebra.dart' show substitute;
-import 'package:kernel/type_environment.dart' show TypeEnvironment;
+import 'package:kernel/type_environment.dart'
+ show SubtypeCheckMode, TypeEnvironment;
import '../builder/builder.dart';
import '../builder/builtin_type_builder.dart';
@@ -3015,11 +3016,12 @@
}
void reportTypeArgumentIssues(
- List<TypeArgumentIssue> issues, Uri fileUri, int offset,
+ Iterable<TypeArgumentIssue> issues, Uri fileUri, int offset,
{bool inferred,
TypeArgumentsInfo typeArgumentsInfo,
DartType targetReceiver,
- String targetName}) {
+ String targetName,
+ bool areWarnings = false}) {
for (TypeArgumentIssue issue in issues) {
DartType argument = issue.argument;
TypeParameter typeParameter = issue.typeParameter;
@@ -3041,16 +3043,27 @@
} else {
if (issue.enclosingType == null && targetReceiver != null) {
if (issueInferred) {
- message =
- templateIncorrectTypeArgumentQualifiedInferred.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- targetReceiver,
- targetName,
- isNonNullableByDefault);
+ Template<
+ Message Function(
+ DartType, DartType, String, DartType, String, bool)>
+ template = areWarnings
+ ? templateIncorrectTypeArgumentQualifiedInferredWarning
+ : templateIncorrectTypeArgumentQualifiedInferred;
+ message = template.withArguments(
+ argument,
+ typeParameter.bound,
+ typeParameter.name,
+ targetReceiver,
+ targetName,
+ isNonNullableByDefault);
} else {
- message = templateIncorrectTypeArgumentQualified.withArguments(
+ Template<
+ Message Function(
+ DartType, DartType, String, DartType, String, bool)>
+ template = areWarnings
+ ? templateIncorrectTypeArgumentQualifiedWarning
+ : templateIncorrectTypeArgumentQualified;
+ message = template.withArguments(
argument,
typeParameter.bound,
typeParameter.name,
@@ -3064,19 +3077,19 @@
: getGenericTypeName(issue.enclosingType);
assert(enclosingName != null);
if (issueInferred) {
- message = templateIncorrectTypeArgumentInferred.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- enclosingName,
- isNonNullableByDefault);
+ Template<Message Function(DartType, DartType, String, String, bool)>
+ template = areWarnings
+ ? templateIncorrectTypeArgumentInferredWarning
+ : templateIncorrectTypeArgumentInferred;
+ message = template.withArguments(argument, typeParameter.bound,
+ typeParameter.name, enclosingName, isNonNullableByDefault);
} else {
- message = templateIncorrectTypeArgument.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- enclosingName,
- isNonNullableByDefault);
+ Template<Message Function(DartType, DartType, String, String, bool)>
+ template = areWarnings
+ ? templateIncorrectTypeArgumentWarning
+ : templateIncorrectTypeArgument;
+ message = template.withArguments(argument, typeParameter.bound,
+ typeParameter.name, enclosingName, isNonNullableByDefault);
}
}
}
@@ -3203,32 +3216,61 @@
}
}
if (returnType != null) {
- List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- returnType, typeEnvironment,
- allowSuperBounded: true);
- if (issues != null) {
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssues(returnType,
+ typeEnvironment, SubtypeCheckMode.ignoringNullabilities,
+ allowSuperBounded: true)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ isNonNullableByDefault && loader.performNnbdChecks
+ ? findTypeArgumentIssues(returnType, typeEnvironment,
+ SubtypeCheckMode.withNullabilities)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null || nnbdIssues != null) {
+ Set<TypeArgumentIssue> mergedIssues = legacyIssues ?? {};
+ if (nnbdIssues != null) {
+ mergedIssues.addAll(nnbdIssues.where((issue) =>
+ legacyIssues == null || !legacyIssues.contains(issue)));
+ }
int offset = fileOffset;
- for (TypeArgumentIssue issue in issues) {
+ for (TypeArgumentIssue issue in mergedIssues) {
DartType argument = issue.argument;
TypeParameter typeParameter = issue.typeParameter;
// We don't need to check if [argument] was inferred or specified
// here, because inference in return types boils down to instantiate-
// -to-bound, and it can't provide a type that violates the bound.
- Message message;
if (argument is FunctionType && argument.typeParameters.length > 0) {
- message = messageGenericFunctionTypeUsedAsActualTypeArgument;
- typeParameter = null;
+ reportTypeArgumentIssue(
+ messageGenericFunctionTypeUsedAsActualTypeArgument,
+ fileUri,
+ offset,
+ null);
} else {
- message = templateIncorrectTypeArgumentInReturnType.withArguments(
- argument,
- typeParameter.bound,
- typeParameter.name,
- getGenericTypeName(issue.enclosingType),
- isNonNullableByDefault);
- }
+ void reportProblem(
+ Template<
+ Message Function(
+ DartType, DartType, String, String, bool)>
+ template) {
+ reportTypeArgumentIssue(
+ template.withArguments(
+ argument,
+ typeParameter.bound,
+ typeParameter.name,
+ getGenericTypeName(issue.enclosingType),
+ isNonNullableByDefault),
+ fileUri,
+ offset,
+ typeParameter);
+ }
- reportTypeArgumentIssue(message, fileUri, offset, typeParameter);
+ nnbdIssues ??= const {};
+ if (nnbdIssues.contains(issue) && !loader.nnbdStrongMode) {
+ reportProblem(templateIncorrectTypeArgumentInReturnTypeWarning);
+ } else {
+ reportProblem(templateIncorrectTypeArgumentInReturnType);
+ }
+ }
}
}
}
@@ -3273,11 +3315,27 @@
void checkBoundsInType(
DartType type, TypeEnvironment typeEnvironment, Uri fileUri, int offset,
{bool inferred, bool allowSuperBounded = true}) {
- List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- type, typeEnvironment,
- allowSuperBounded: allowSuperBounded);
- if (issues != null) {
- reportTypeArgumentIssues(issues, fileUri, offset, inferred: inferred);
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssues(
+ type, typeEnvironment, SubtypeCheckMode.ignoringNullabilities,
+ allowSuperBounded: allowSuperBounded)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ isNonNullableByDefault && loader.performNnbdChecks
+ ? findTypeArgumentIssues(
+ type, typeEnvironment, SubtypeCheckMode.withNullabilities,
+ allowSuperBounded: allowSuperBounded)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null) {
+ reportTypeArgumentIssues(legacyIssues, fileUri, offset,
+ inferred: inferred);
+ }
+ if (nnbdIssues != null) {
+ if (legacyIssues != null) {
+ nnbdIssues = nnbdIssues.where((issue) => !legacyIssues.contains(issue));
+ }
+ reportTypeArgumentIssues(nnbdIssues, fileUri, offset,
+ inferred: inferred, areWarnings: !loader.nnbdStrongMode);
}
}
@@ -3330,20 +3388,46 @@
List<DartType> arguments = node.arguments.types;
// The following error is to be reported elsewhere.
if (parameters.length != arguments.length) return;
- List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
- parameters, arguments, typeEnvironment);
- if (issues != null) {
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssuesForInvocation(
+ parameters,
+ arguments,
+ typeEnvironment,
+ SubtypeCheckMode.ignoringNullabilities)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ isNonNullableByDefault && loader.performNnbdChecks
+ ? findTypeArgumentIssuesForInvocation(parameters, arguments,
+ typeEnvironment, SubtypeCheckMode.withNullabilities)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null) {
DartType targetReceiver;
if (klass != null) {
targetReceiver =
new InterfaceType(klass, klass.enclosingLibrary.nonNullable);
}
String targetName = node.target.name.name;
- reportTypeArgumentIssues(issues, fileUri, node.fileOffset,
+ reportTypeArgumentIssues(legacyIssues, fileUri, node.fileOffset,
typeArgumentsInfo: typeArgumentsInfo,
targetReceiver: targetReceiver,
targetName: targetName);
}
+ if (nnbdIssues != null) {
+ DartType targetReceiver;
+ if (klass != null) {
+ targetReceiver =
+ new InterfaceType(klass, klass.enclosingLibrary.nonNullable);
+ }
+ String targetName = node.target.name.name;
+ if (legacyIssues != null) {
+ nnbdIssues = nnbdIssues.where((issue) => !legacyIssues.contains(issue));
+ }
+ reportTypeArgumentIssues(nnbdIssues, fileUri, node.fileOffset,
+ typeArgumentsInfo: typeArgumentsInfo,
+ targetReceiver: targetReceiver,
+ targetName: targetName,
+ areWarnings: !loader.nnbdStrongMode);
+ }
}
void checkBoundsInMethodInvocation(
@@ -3396,14 +3480,37 @@
instantiatedMethodParameters[i].bound =
substitute(methodParameters[i].bound, substitutionMap);
}
- List<TypeArgumentIssue> issues = findTypeArgumentIssuesForInvocation(
- instantiatedMethodParameters, arguments.types, typeEnvironment);
- if (issues != null) {
- reportTypeArgumentIssues(issues, fileUri, offset,
+ Set<TypeArgumentIssue> legacyIssues = findTypeArgumentIssuesForInvocation(
+ instantiatedMethodParameters,
+ arguments.types,
+ typeEnvironment,
+ SubtypeCheckMode.ignoringNullabilities)
+ ?.toSet();
+ Set<TypeArgumentIssue> nnbdIssues =
+ isNonNullableByDefault && loader.performNnbdChecks
+ ? findTypeArgumentIssuesForInvocation(
+ instantiatedMethodParameters,
+ arguments.types,
+ typeEnvironment,
+ SubtypeCheckMode.withNullabilities)
+ ?.toSet()
+ : null;
+ if (legacyIssues != null) {
+ reportTypeArgumentIssues(legacyIssues, fileUri, offset,
typeArgumentsInfo: getTypeArgumentsInfo(arguments),
targetReceiver: receiverType,
targetName: name.name);
}
+ if (nnbdIssues != null) {
+ if (legacyIssues != null) {
+ nnbdIssues = nnbdIssues.where((issue) => !legacyIssues.contains(issue));
+ }
+ reportTypeArgumentIssues(nnbdIssues, fileUri, offset,
+ typeArgumentsInfo: getTypeArgumentsInfo(arguments),
+ targetReceiver: receiverType,
+ targetName: name.name,
+ areWarnings: !loader.nnbdStrongMode);
+ }
}
void checkTypesInOutline(TypeEnvironment typeEnvironment) {
diff --git a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
index 6257581..5dc83a6 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/standard_bounds.dart
@@ -419,6 +419,15 @@
DartType getNullabilityObliviousStandardLowerBound(
DartType type1, DartType type2, Library clientLibrary) {
+ // Do legacy erasure on the argument, so that the result types that are
+ // computed from arguments are legacy.
+ type1 = type1 == coreTypes.nullType
+ ? type1
+ : type1.withNullability(Nullability.legacy);
+ type2 = type2 == coreTypes.nullType
+ ? type2
+ : type2.withNullability(Nullability.legacy);
+
// For all types T, SLB(T,T) = T. Note that we don't test for equality
// because we don't want to make the algorithm quadratic. This is ok
// because the check is not needed for correctness; it's just a speed
@@ -1390,10 +1399,10 @@
// 3. Otherwise return the spec-defined standard upper bound. This will
// be an upper bound, might (or might not) be least, and might
// (or might not) be a well-formed type.
- if (isSubtypeOf(type1, type2, SubtypeCheckMode.ignoringNullabilities)) {
+ if (isSubtypeOf(type1, type2, SubtypeCheckMode.withNullabilities)) {
return type2;
}
- if (isSubtypeOf(type2, type1, SubtypeCheckMode.ignoringNullabilities)) {
+ if (isSubtypeOf(type2, type1, SubtypeCheckMode.withNullabilities)) {
return type1;
}
if (type1 is InterfaceType &&
@@ -1411,7 +1420,7 @@
tArgs[i] = getStandardLowerBound(tArgs1[i], tArgs2[i], clientLibrary);
} else if (tParams[i].variance == Variance.invariant) {
if (!areMutualSubtypes(
- tArgs1[i], tArgs2[i], SubtypeCheckMode.ignoringNullabilities)) {
+ tArgs1[i], tArgs2[i], SubtypeCheckMode.withNullabilities)) {
// No bound will be valid, find bound at the interface level.
return getLegacyLeastUpperBound(type1, type2, clientLibrary);
}
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
index e90f6b9..eff3fb7 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_inferrer.dart
@@ -343,7 +343,7 @@
DartType inferredType =
inferrer.inferReturnType(_inferredUnwrappedReturnOrYieldType);
if (!inferrer.typeSchemaEnvironment.isSubtypeOf(inferredType,
- returnOrYieldContext, SubtypeCheckMode.ignoringNullabilities)) {
+ returnOrYieldContext, SubtypeCheckMode.withNullabilities)) {
// If the inferred return type isn't a subtype of the context, we use the
// context.
inferredType = greatestClosure(inferrer.coreTypes, returnOrYieldContext);
@@ -1140,8 +1140,8 @@
DartType typeArgument = inferredTypeArguments[index];
DartType bound =
inferredSubstitution.substituteType(typeParameter.bound);
- if (!typeSchemaEnvironment.isSubtypeOf(typeArgument, bound,
- SubtypeCheckMode.ignoringNullabilities)) {
+ if (!typeSchemaEnvironment.isSubtypeOf(
+ typeArgument, bound, SubtypeCheckMode.withNullabilities)) {
return;
}
}
@@ -4257,9 +4257,9 @@
if (this.isPlatform == other.isPlatform) {
// Both are platform or not platform.
bool thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
- this.onType, other.onType, SubtypeCheckMode.ignoringNullabilities);
+ this.onType, other.onType, SubtypeCheckMode.withNullabilities);
bool thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
- other.onType, this.onType, SubtypeCheckMode.ignoringNullabilities);
+ other.onType, this.onType, SubtypeCheckMode.withNullabilities);
if (thisIsSubtype && !thisIsSupertype) {
// This is subtype of other and not vice-versa.
return true;
@@ -4270,11 +4270,11 @@
thisIsSubtype = typeSchemaEnvironment.isSubtypeOf(
this.onTypeInstantiateToBounds,
other.onTypeInstantiateToBounds,
- SubtypeCheckMode.ignoringNullabilities);
+ SubtypeCheckMode.withNullabilities);
thisIsSupertype = typeSchemaEnvironment.isSubtypeOf(
other.onTypeInstantiateToBounds,
this.onTypeInstantiateToBounds,
- SubtypeCheckMode.ignoringNullabilities);
+ SubtypeCheckMode.withNullabilities);
if (thisIsSubtype && !thisIsSupertype) {
// This is subtype of other and not vice-versa.
return true;
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
index 11c5323..4a8dca0 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_promotion.dart
@@ -686,13 +686,13 @@
// the variable and the type we are checking against.
DartType previousType = previousPromotedType ?? variable.type;
if (promoter.typeSchemaEnvironment.isSubtypeOf(
- checkedType, previousType, SubtypeCheckMode.ignoringNullabilities)) {
+ checkedType, previousType, SubtypeCheckMode.withNullabilities)) {
// The type we are checking against is a subtype of the previous type of
// the variable, so this is a refinement; we can promote.
return checkedType;
} else if (previousType is TypeParameterType &&
promoter.typeSchemaEnvironment.isSubtypeOf(checkedType,
- previousType.bound, SubtypeCheckMode.ignoringNullabilities)) {
+ previousType.bound, SubtypeCheckMode.withNullabilities)) {
// The type we are checking against is a subtype of the bound of the
// previous type of the variable; we can promote the bound.
return new TypeParameterType.intersection(
diff --git a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
index 789301a..ada372b 100644
--- a/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
+++ b/pkg/front_end/lib/src/fasta/type_inference/type_schema_environment.dart
@@ -163,10 +163,10 @@
// override.
if (type1 is InterfaceType && type1.classNode == coreTypes.intClass) {
if (type2 is InterfaceType && type2.classNode == coreTypes.intClass) {
- return type2;
+ return type2.withNullability(type1.nullability);
}
if (type2 is InterfaceType && type2.classNode == coreTypes.doubleClass) {
- return type2;
+ return type2.withNullability(type1.nullability);
}
}
return coreTypes.numRawType(type1.nullability);
@@ -326,8 +326,8 @@
if (success && !hasOmittedBound(typeParam)) {
// If everything else succeeded, check the `extends` constraint.
DartType extendsConstraint = typeParamBound;
- success = isSubtypeOf(inferred, extendsConstraint,
- SubtypeCheckMode.ignoringNullabilities);
+ success = isSubtypeOf(
+ inferred, extendsConstraint, SubtypeCheckMode.withNullabilities);
}
if (!success) {
@@ -351,7 +351,15 @@
bool isSubtypeOf(
DartType subtype, DartType supertype, SubtypeCheckMode mode) {
if (subtype is UnknownType) return true;
- if (subtype == Null && supertype is UnknownType) return true;
+ DartType unwrappedSupertype = supertype;
+ while (unwrappedSupertype is InterfaceType &&
+ unwrappedSupertype.classNode == futureOrClass) {
+ unwrappedSupertype =
+ (unwrappedSupertype as InterfaceType).typeArguments.single;
+ }
+ if (subtype == coreTypes.nullType && unwrappedSupertype is UnknownType) {
+ return true;
+ }
return super.isSubtypeOf(subtype, supertype, mode);
}
@@ -444,9 +452,8 @@
/// Determine if the given [type] satisfies the given type [constraint].
bool typeSatisfiesConstraint(DartType type, TypeConstraint constraint) {
return isSubtypeOf(
- constraint.lower, type, SubtypeCheckMode.ignoringNullabilities) &&
- isSubtypeOf(
- type, constraint.upper, SubtypeCheckMode.ignoringNullabilities);
+ constraint.lower, type, SubtypeCheckMode.withNullabilities) &&
+ isSubtypeOf(type, constraint.upper, SubtypeCheckMode.withNullabilities);
}
DartType _inferTypeParameterFromAll(
diff --git a/pkg/front_end/messages.status b/pkg/front_end/messages.status
index dd4f20c..869d90b 100644
--- a/pkg/front_end/messages.status
+++ b/pkg/front_end/messages.status
@@ -360,6 +360,14 @@
ImportAfterPart/script1: Fail
IncompatibleRedirecteeFunctionType/part_wrapped_script6: Fail
IncompatibleRedirecteeFunctionType/script6: Fail # Triggers multiple errors.
+IncompatibleRedirecteeFunctionTypeWarning/example: Fail
+IncorrectTypeArgumentInReturnTypeWarning/example: Fail
+IncorrectTypeArgumentInSupertypeInferredWarning/example: Fail
+IncorrectTypeArgumentInSupertypeWarning/example: Fail
+IncorrectTypeArgumentInferredWarning/example: Fail
+IncorrectTypeArgumentQualifiedInferredWarning/example: Fail
+IncorrectTypeArgumentQualifiedWarning/example: Fail
+IncorrectTypeArgumentWarning/example: Fail
InitializerForStaticField/example: Fail
InitializerOutsideConstructor/example: Fail
InputFileNotFound/analyzerCode: Fail
@@ -528,8 +536,11 @@
OverrideMismatchNamedParameter/example: Fail
OverrideMoreRequiredArguments/example: Fail
OverrideTypeMismatchParameter/example: Fail
+OverrideTypeMismatchParameterWarning/example: Fail
OverrideTypeMismatchReturnType/example: Fail
+OverrideTypeMismatchReturnTypeWarning/example: Fail
OverrideTypeMismatchSetter/example: Fail
+OverrideTypeMismatchSetterWarning/example: Fail
OverrideTypeVariablesBoundMismatch/analyzerCode: Fail
OverrideTypeVariablesBoundMismatch/example: Fail
OverrideTypeVariablesMismatch/example: Fail
@@ -566,6 +577,7 @@
PrivateNamedParameter/example: Fail
RedirectingConstructorWithBody/part_wrapped_script1: Fail
RedirectingConstructorWithBody/script1: Fail
+RedirectingFactoryIncompatibleTypeArgumentWarning/example: Fail
RedirectionInNonFactory/part_wrapped_script1: Fail
RedirectionInNonFactory/script1: Fail
RedirectionTargetNotFound/example: Fail
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 79fc4f4..a5b9d37 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -2059,15 +2059,32 @@
tip: "Change to a supertype of '#type2', or, for a covariant parameter, a subtype."
analyzerCode: INVALID_METHOD_OVERRIDE
+OverrideTypeMismatchParameterWarning:
+ template: "The parameter '#name' of the method '#name2' has type '#type', which does not match the corresponding type, '#type2', in the overridden method, '#name3'."
+ tip: "Change to a supertype of '#type2', or, for a covariant parameter, a subtype."
+ severity: WARNING
+ analyzerCode: INVALID_METHOD_OVERRIDE
+
OverrideTypeMismatchReturnType:
template: "The return type of the method '#name' is '#type', which does not match the return type, '#type2', of the overridden method, '#name2'."
tip: "Change to a subtype of '#type2'."
analyzerCode: INVALID_METHOD_OVERRIDE
+OverrideTypeMismatchReturnTypeWarning:
+ template: "The return type of the method '#name' is '#type', which does not match the return type, '#type2', of the overridden method, '#name2'."
+ tip: "Change to a subtype of '#type2'."
+ severity: WARNING
+ analyzerCode: INVALID_METHOD_OVERRIDE
+
OverrideTypeMismatchSetter:
template: "The field '#name' has type '#type', which does not match the corresponding type, '#type2', in the overridden setter, '#name2'."
analyzerCode: INVALID_METHOD_OVERRIDE
+OverrideTypeMismatchSetterWarning:
+ template: "The field '#name' has type '#type', which does not match the corresponding type, '#type2', in the overridden setter, '#name2'."
+ severity: WARNING
+ analyzerCode: INVALID_METHOD_OVERRIDE
+
PartOfSelf:
template: "A file can't be a part of itself."
analyzerCode: PART_OF_NON_PART
@@ -3354,6 +3371,11 @@
}
class B<T extends int, S extends String> implements A<T> {}
+IncompatibleRedirecteeFunctionTypeWarning:
+ template: "The constructor function type '#type' isn't a subtype of '#type2'."
+ severity: WARNING
+ analyzerCode: REDIRECT_TO_INVALID_TYPE
+
RedirectingFactoryIncompatibleTypeArgument:
template: "The type '#type' doesn't extend '#type2'."
tip: "Try using a different type as argument."
@@ -3365,6 +3387,12 @@
}
class B<T extends int, S extends String> implements A<T> {}
+RedirectingFactoryIncompatibleTypeArgumentWarning:
+ template: "The type '#type' doesn't extend '#type2'."
+ tip: "Try using a different type as argument."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
SyntheticToken:
template: "This couldn't be parsed."
frontendInternal: true
@@ -3377,6 +3405,12 @@
class C<T extends num> {}
main() { new C<String>(); }
+IncorrectTypeArgumentWarning:
+ template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2'."
+ tip: "Try changing type arguments so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentQualified:
template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'."
tip: "Try changing type arguments so that they conform to the bounds."
@@ -3385,6 +3419,12 @@
class C<T> { foo<U extends num>() {} }
main() { new C<String>().foo<String>(); }
+IncorrectTypeArgumentQualifiedWarning:
+ template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'."
+ tip: "Try changing type arguments so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentInSupertype:
template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'."
tip: "Try changing type arguments so that they conform to the bounds."
@@ -3393,6 +3433,12 @@
class A<T extends num> {}
class B extends A<String> {}
+IncorrectTypeArgumentInSupertypeWarning:
+ template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'."
+ tip: "Try changing type arguments so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentInReturnType:
template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the return type."
tip: "Try changing type arguments so that they conform to the bounds."
@@ -3401,6 +3447,12 @@
class A<T extends num> {}
A<String> foo() => null;
+IncorrectTypeArgumentInReturnTypeWarning:
+ template: "Type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the return type."
+ tip: "Try changing type arguments so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentInferred:
template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2'."
tip: "Try specifying type arguments explicitly so that they conform to the bounds."
@@ -3409,6 +3461,12 @@
void foo<T extends num>(T t) {}
main() { foo("bar"); }
+IncorrectTypeArgumentInferredWarning:
+ template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2'."
+ tip: "Try specifying type arguments explicitly so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentQualifiedInferred:
template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'."
tip: "Try specifying type arguments explicitly so that they conform to the bounds."
@@ -3417,6 +3475,12 @@
class C<T> { foo<U extends num>(U u) {} }
main() { new C<String>().foo(""); }
+IncorrectTypeArgumentQualifiedInferredWarning:
+ template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#type3.#name2'."
+ tip: "Try specifying type arguments explicitly so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentInSupertypeInferred:
template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'."
tip: "Try specifying type arguments explicitly so that they conform to the bounds."
@@ -3425,6 +3489,12 @@
class A<T extends A<T>> {}
class B extends A {}
+IncorrectTypeArgumentInSupertypeInferredWarning:
+ template: "Inferred type argument '#type' doesn't conform to the bound '#type2' of the type variable '#name' on '#name2' in the supertype '#name3' of class '#name4'."
+ tip: "Try specifying type arguments explicitly so that they conform to the bounds."
+ severity: WARNING
+ analyzerCode: TYPE_ARGUMENT_NOT_MATCHING_BOUNDS
+
IncorrectTypeArgumentVariable:
template: "This is the type variable whose bound isn't conformed to."
severity: CONTEXT
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart b/pkg/front_end/testcases/nnbd/bounds_checks.dart
new file mode 100644
index 0000000..3250d57
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart
@@ -0,0 +1,28 @@
+// 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 file.
+
+class A<X extends num> {}
+
+foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+
+A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+
+baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+
+class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+
+class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+
+void hest<T extends num>() {}
+
+class Hest {
+ void hest<T extends num>() {}
+}
+
+fisk(Hest h) {
+ hest<num?>();
+ h.hest<num?>();
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.outline.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.outline.expect
new file mode 100644
index 0000000..a66b2fe
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.outline.expect
@@ -0,0 +1,77 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:7:13: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:9:12: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the return type.
+// Try changing type arguments so that they conform to the bounds.
+// A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:11:5: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:13:7: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the supertype 'A' of class 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:15:9: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+class B extends self::A<core::num?> {
+ synthetic constructor •() → self::B
+ ;
+}
+class C<T extends self::A<core::num?> = self::A<core::num?>> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T>
+ ;
+}
+class Hest extends core::Object {
+ synthetic constructor •() → self::Hest
+ ;
+ method hest<T extends core::num = core::num>() → void
+ ;
+}
+static method foo(self::A<core::num?> a) → dynamic
+ ;
+static method bar() → self::A<core::num?>
+ ;
+static method baz<T extends self::A<core::num?> = self::A<core::num?>>() → dynamic
+ ;
+static method hest<T extends core::num = core::num>() → void
+ ;
+static method fisk(self::Hest h) → dynamic
+ ;
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.expect
new file mode 100644
index 0000000..686cc68
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.expect
@@ -0,0 +1,91 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:7:13: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:9:12: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the return type.
+// Try changing type arguments so that they conform to the bounds.
+// A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:11:5: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:13:7: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the supertype 'A' of class 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:15:9: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:24:3: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'hest'.
+// Try changing type arguments so that they conform to the bounds.
+// hest<num?>();
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// void hest<T extends num>() {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:25:5: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'Hest.hest'.
+// - 'Hest' is from 'pkg/front_end/testcases/nnbd/bounds_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// h.hest<num?>();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<core::num?> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<T extends self::A<core::num?> = self::A<core::num?>> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T>
+ : super core::Object::•()
+ ;
+}
+class Hest extends core::Object {
+ synthetic constructor •() → self::Hest
+ : super core::Object::•()
+ ;
+ method hest<T extends core::num = core::num>() → void {}
+}
+static method foo(self::A<core::num?> a) → dynamic {}
+static method bar() → self::A<core::num?> {}
+static method baz<T extends self::A<core::num?> = self::A<core::num?>>() → dynamic {}
+static method hest<T extends core::num = core::num>() → void {}
+static method fisk(self::Hest h) → dynamic {
+ self::hest<core::num?>();
+ h.{self::Hest::hest}<core::num?>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.transformed.expect
new file mode 100644
index 0000000..686cc68
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.strong.transformed.expect
@@ -0,0 +1,91 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:7:13: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:9:12: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the return type.
+// Try changing type arguments so that they conform to the bounds.
+// A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:11:5: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:13:7: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the supertype 'A' of class 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:15:9: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:24:3: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'hest'.
+// Try changing type arguments so that they conform to the bounds.
+// hest<num?>();
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// void hest<T extends num>() {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:25:5: Error: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'Hest.hest'.
+// - 'Hest' is from 'pkg/front_end/testcases/nnbd/bounds_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// h.hest<num?>();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<core::num?> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<T extends self::A<core::num?> = self::A<core::num?>> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T>
+ : super core::Object::•()
+ ;
+}
+class Hest extends core::Object {
+ synthetic constructor •() → self::Hest
+ : super core::Object::•()
+ ;
+ method hest<T extends core::num = core::num>() → void {}
+}
+static method foo(self::A<core::num?> a) → dynamic {}
+static method bar() → self::A<core::num?> {}
+static method baz<T extends self::A<core::num?> = self::A<core::num?>>() → dynamic {}
+static method hest<T extends core::num = core::num>() → void {}
+static method fisk(self::Hest h) → dynamic {
+ self::hest<core::num?>();
+ h.{self::Hest::hest}<core::num?>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.expect
new file mode 100644
index 0000000..d78654a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.expect
@@ -0,0 +1,91 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:7:13: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:9:12: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the return type.
+// Try changing type arguments so that they conform to the bounds.
+// A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:11:5: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:13:7: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the supertype 'A' of class 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:15:9: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:24:3: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'hest'.
+// Try changing type arguments so that they conform to the bounds.
+// hest<num?>();
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// void hest<T extends num>() {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:25:5: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'Hest.hest'.
+// - 'Hest' is from 'pkg/front_end/testcases/nnbd/bounds_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// h.hest<num?>();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<core::num?> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<T extends self::A<core::num?> = self::A<core::num?>> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T>
+ : super core::Object::•()
+ ;
+}
+class Hest extends core::Object {
+ synthetic constructor •() → self::Hest
+ : super core::Object::•()
+ ;
+ method hest<T extends core::num = core::num>() → void {}
+}
+static method foo(self::A<core::num?> a) → dynamic {}
+static method bar() → self::A<core::num?> {}
+static method baz<T extends self::A<core::num?> = self::A<core::num?>>() → dynamic {}
+static method hest<T extends core::num = core::num>() → void {}
+static method fisk(self::Hest h) → dynamic {
+ self::hest<core::num?>();
+ h.{self::Hest::hest}<core::num?>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.transformed.expect
new file mode 100644
index 0000000..d78654a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/bounds_checks.dart.weak.transformed.expect
@@ -0,0 +1,91 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:7:13: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// foo(A<num?> a) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:9:12: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the return type.
+// Try changing type arguments so that they conform to the bounds.
+// A<num?> bar() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:11:5: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// baz<T extends A<num?>>() {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:13:7: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A' in the supertype 'A' of class 'B'.
+// Try changing type arguments so that they conform to the bounds.
+// class B extends A<num?> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:15:9: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'X' on 'A'.
+// Try changing type arguments so that they conform to the bounds.
+// class C<T extends A<num?>> {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:5:9: Context: This is the type variable whose bound isn't conformed to.
+// class A<X extends num> {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:24:3: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'hest'.
+// Try changing type arguments so that they conform to the bounds.
+// hest<num?>();
+// ^
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:17:11: Context: This is the type variable whose bound isn't conformed to.
+// void hest<T extends num>() {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/bounds_checks.dart:25:5: Warning: Type argument 'num?' doesn't conform to the bound 'num' of the type variable 'T' on 'Hest.hest'.
+// - 'Hest' is from 'pkg/front_end/testcases/nnbd/bounds_checks.dart'.
+// Try changing type arguments so that they conform to the bounds.
+// h.hest<num?>();
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B extends self::A<core::num?> {
+ synthetic constructor •() → self::B
+ : super self::A::•()
+ ;
+}
+class C<T extends self::A<core::num?> = self::A<core::num?>> extends core::Object {
+ synthetic constructor •() → self::C<self::C::T>
+ : super core::Object::•()
+ ;
+}
+class Hest extends core::Object {
+ synthetic constructor •() → self::Hest
+ : super core::Object::•()
+ ;
+ method hest<T extends core::num = core::num>() → void {}
+}
+static method foo(self::A<core::num?> a) → dynamic {}
+static method bar() → self::A<core::num?> {}
+static method baz<T extends self::A<core::num?> = self::A<core::num?>>() → dynamic {}
+static method hest<T extends core::num = core::num>() → void {}
+static method fisk(self::Hest h) → dynamic {
+ self::hest<core::num?>();
+ h.{self::Hest::hest}<core::num?>();
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart
new file mode 100644
index 0000000..739c609
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart
@@ -0,0 +1,16 @@
+// 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 file.
+
+// @dart=2.6
+
+// The test checks that a legacy type is inferred even if some of the input
+// types are from opted-in libraries.
+
+import './infer_in_legacy_from_opted_in_lib.dart';
+
+bar(int x) {
+ baz(foo(x, y));
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.outline.expect
new file mode 100644
index 0000000..f226132
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.outline.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///infer_in_legacy_from_opted_in_lib.dart";
+
+static method bar(core::int* x) → dynamic
+ ;
+static method main() → dynamic
+ ;
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+static field core::int y;
+static method foo<T extends core::num = core::num>(self2::foo::T t1, self2::foo::T t2) → self2::foo::T
+ ;
+static method baz(core::int? v) → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.expect
new file mode 100644
index 0000000..52dc9a8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "infer_in_legacy_from_opted_in_lib.dart" as inf;
+
+import "org-dartlang-testcase:///infer_in_legacy_from_opted_in_lib.dart";
+
+static method bar(core::int* x) → dynamic {
+ inf::baz(inf::foo<core::int*>(x, inf::y));
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int y = 42;
+static method foo<T extends core::num = core::num>(inf::foo::T t1, inf::foo::T t2) → inf::foo::T
+ return t1;
+static method baz(core::int? v) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.transformed.expect
new file mode 100644
index 0000000..52dc9a8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.strong.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "infer_in_legacy_from_opted_in_lib.dart" as inf;
+
+import "org-dartlang-testcase:///infer_in_legacy_from_opted_in_lib.dart";
+
+static method bar(core::int* x) → dynamic {
+ inf::baz(inf::foo<core::int*>(x, inf::y));
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int y = 42;
+static method foo<T extends core::num = core::num>(inf::foo::T t1, inf::foo::T t2) → inf::foo::T
+ return t1;
+static method baz(core::int? v) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.expect
new file mode 100644
index 0000000..52dc9a8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "infer_in_legacy_from_opted_in_lib.dart" as inf;
+
+import "org-dartlang-testcase:///infer_in_legacy_from_opted_in_lib.dart";
+
+static method bar(core::int* x) → dynamic {
+ inf::baz(inf::foo<core::int*>(x, inf::y));
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int y = 42;
+static method foo<T extends core::num = core::num>(inf::foo::T t1, inf::foo::T t2) → inf::foo::T
+ return t1;
+static method baz(core::int? v) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.transformed.expect
new file mode 100644
index 0000000..52dc9a8
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in.dart.weak.transformed.expect
@@ -0,0 +1,20 @@
+library;
+import self as self;
+import "dart:core" as core;
+import "infer_in_legacy_from_opted_in_lib.dart" as inf;
+
+import "org-dartlang-testcase:///infer_in_legacy_from_opted_in_lib.dart";
+
+static method bar(core::int* x) → dynamic {
+ inf::baz(inf::foo<core::int*>(x, inf::y));
+}
+static method main() → dynamic {}
+
+library /*isNonNullableByDefault*/;
+import self as inf;
+import "dart:core" as core;
+
+static field core::int y = 42;
+static method foo<T extends core::num = core::num>(inf::foo::T t1, inf::foo::T t2) → inf::foo::T
+ return t1;
+static method baz(core::int? v) → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in_lib.dart b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in_lib.dart
new file mode 100644
index 0000000..75230d2
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/infer_in_legacy_from_opted_in_lib.dart
@@ -0,0 +1,9 @@
+// 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 file.
+
+T foo<T extends num>(T t1, T t2) => t1;
+
+int y = 42;
+
+baz(int? v) {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.outline.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.outline.expect
index 331438b..23d3652 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.outline.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.outline.expect
@@ -46,30 +46,30 @@
;
set property4(core::int* value) → void
;
- abstract member-signature get property6() → core::int*;
+ abstract forwarding-stub member-signature get property6() → core::int*;
abstract member-signature get getter1() → core::int*;
abstract member-signature get field1() → core::int*;
- abstract member-signature get field2() → core::int*;
- abstract member-signature get getter2() → core::int*;
+ abstract forwarding-stub member-signature get field2() → core::int*;
+ abstract forwarding-stub member-signature get getter2() → core::int*;
abstract member-signature method method5a(core::int* a, core::int* b) → core::int*;
abstract member-signature method method9a(core::int* a, {core::int* b}) → core::int*;
abstract member-signature method method5c([core::int* a, core::int* b]) → core::int*;
abstract member-signature get property5() → core::int*;
- abstract member-signature method method2() → core::int*;
+ abstract forwarding-stub member-signature method method2() → core::int*;
abstract member-signature method method7a(core::int* a, {core::int* b}) → core::int*;
abstract member-signature method method5b(core::int* a, [core::int* b]) → core::int*;
abstract member-signature method method9b({core::int* a, core::int* b}) → core::int*;
abstract member-signature method method1() → core::int*;
abstract member-signature get property1() → core::int*;
- abstract member-signature get property2() → core::int*;
+ abstract forwarding-stub member-signature get property2() → core::int*;
abstract member-signature method method7b({core::int* a, core::int* b}) → core::int*;
- abstract member-signature set setter1(core::int* value) → void;
+ abstract forwarding-stub member-signature set setter1(core::int* value) → void;
abstract member-signature set property6(core::int* _) → void;
- abstract member-signature set field1(core::int* _) → void;
+ abstract forwarding-stub member-signature set field1(core::int* _) → void;
abstract member-signature set field2(core::int* _) → void;
- abstract member-signature set property5(core::int* _) → void;
+ abstract forwarding-stub member-signature set property5(core::int* value) → void;
abstract member-signature set setter2(core::int* value) → void;
- abstract member-signature set property1(core::int* value) → void;
+ abstract forwarding-stub member-signature set property1(core::int* value) → void;
abstract member-signature set property2(core::int* value) → void;
}
static method main() → dynamic
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.expect
index a926f8b..6208ce9 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.expect
@@ -43,30 +43,30 @@
get property4() → core::int*
return 0;
set property4(core::int* value) → void {}
- abstract member-signature get property6() → core::int*;
+ abstract forwarding-stub member-signature get property6() → core::int*;
abstract member-signature get getter1() → core::int*;
abstract member-signature get field1() → core::int*;
- abstract member-signature get field2() → core::int*;
- abstract member-signature get getter2() → core::int*;
+ abstract forwarding-stub member-signature get field2() → core::int*;
+ abstract forwarding-stub member-signature get getter2() → core::int*;
abstract member-signature method method5a(core::int* a, core::int* b) → core::int*;
abstract member-signature method method9a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5c([core::int* a = #C2, core::int* b = #C1]) → core::int*;
abstract member-signature get property5() → core::int*;
- abstract member-signature method method2() → core::int*;
+ abstract forwarding-stub member-signature method method2() → core::int*;
abstract member-signature method method7a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5b(core::int* a, [core::int* b = #C1]) → core::int*;
abstract member-signature method method9b({core::int* a = #C1, core::int* b = #C1}) → core::int*;
abstract member-signature method method1() → core::int*;
abstract member-signature get property1() → core::int*;
- abstract member-signature get property2() → core::int*;
+ abstract forwarding-stub member-signature get property2() → core::int*;
abstract member-signature method method7b({core::int* a = #C2, core::int* b = #C1}) → core::int*;
- abstract member-signature set setter1(core::int* value) → void;
+ abstract forwarding-stub member-signature set setter1(core::int* value) → void;
abstract member-signature set property6(core::int* _) → void;
- abstract member-signature set field1(core::int* _) → void;
+ abstract forwarding-stub member-signature set field1(core::int* _) → void;
abstract member-signature set field2(core::int* _) → void;
- abstract member-signature set property5(core::int* _) → void;
+ abstract forwarding-stub member-signature set property5(core::int* value) → void;
abstract member-signature set setter2(core::int* value) → void;
- abstract member-signature set property1(core::int* value) → void;
+ abstract forwarding-stub member-signature set property1(core::int* value) → void;
abstract member-signature set property2(core::int* value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.transformed.expect
index a926f8b..6208ce9 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.strong.transformed.expect
@@ -43,30 +43,30 @@
get property4() → core::int*
return 0;
set property4(core::int* value) → void {}
- abstract member-signature get property6() → core::int*;
+ abstract forwarding-stub member-signature get property6() → core::int*;
abstract member-signature get getter1() → core::int*;
abstract member-signature get field1() → core::int*;
- abstract member-signature get field2() → core::int*;
- abstract member-signature get getter2() → core::int*;
+ abstract forwarding-stub member-signature get field2() → core::int*;
+ abstract forwarding-stub member-signature get getter2() → core::int*;
abstract member-signature method method5a(core::int* a, core::int* b) → core::int*;
abstract member-signature method method9a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5c([core::int* a = #C2, core::int* b = #C1]) → core::int*;
abstract member-signature get property5() → core::int*;
- abstract member-signature method method2() → core::int*;
+ abstract forwarding-stub member-signature method method2() → core::int*;
abstract member-signature method method7a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5b(core::int* a, [core::int* b = #C1]) → core::int*;
abstract member-signature method method9b({core::int* a = #C1, core::int* b = #C1}) → core::int*;
abstract member-signature method method1() → core::int*;
abstract member-signature get property1() → core::int*;
- abstract member-signature get property2() → core::int*;
+ abstract forwarding-stub member-signature get property2() → core::int*;
abstract member-signature method method7b({core::int* a = #C2, core::int* b = #C1}) → core::int*;
- abstract member-signature set setter1(core::int* value) → void;
+ abstract forwarding-stub member-signature set setter1(core::int* value) → void;
abstract member-signature set property6(core::int* _) → void;
- abstract member-signature set field1(core::int* _) → void;
+ abstract forwarding-stub member-signature set field1(core::int* _) → void;
abstract member-signature set field2(core::int* _) → void;
- abstract member-signature set property5(core::int* _) → void;
+ abstract forwarding-stub member-signature set property5(core::int* value) → void;
abstract member-signature set setter2(core::int* value) → void;
- abstract member-signature set property1(core::int* value) → void;
+ abstract forwarding-stub member-signature set property1(core::int* value) → void;
abstract member-signature set property2(core::int* value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.expect
index a926f8b..6208ce9 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.expect
@@ -43,30 +43,30 @@
get property4() → core::int*
return 0;
set property4(core::int* value) → void {}
- abstract member-signature get property6() → core::int*;
+ abstract forwarding-stub member-signature get property6() → core::int*;
abstract member-signature get getter1() → core::int*;
abstract member-signature get field1() → core::int*;
- abstract member-signature get field2() → core::int*;
- abstract member-signature get getter2() → core::int*;
+ abstract forwarding-stub member-signature get field2() → core::int*;
+ abstract forwarding-stub member-signature get getter2() → core::int*;
abstract member-signature method method5a(core::int* a, core::int* b) → core::int*;
abstract member-signature method method9a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5c([core::int* a = #C2, core::int* b = #C1]) → core::int*;
abstract member-signature get property5() → core::int*;
- abstract member-signature method method2() → core::int*;
+ abstract forwarding-stub member-signature method method2() → core::int*;
abstract member-signature method method7a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5b(core::int* a, [core::int* b = #C1]) → core::int*;
abstract member-signature method method9b({core::int* a = #C1, core::int* b = #C1}) → core::int*;
abstract member-signature method method1() → core::int*;
abstract member-signature get property1() → core::int*;
- abstract member-signature get property2() → core::int*;
+ abstract forwarding-stub member-signature get property2() → core::int*;
abstract member-signature method method7b({core::int* a = #C2, core::int* b = #C1}) → core::int*;
- abstract member-signature set setter1(core::int* value) → void;
+ abstract forwarding-stub member-signature set setter1(core::int* value) → void;
abstract member-signature set property6(core::int* _) → void;
- abstract member-signature set field1(core::int* _) → void;
+ abstract forwarding-stub member-signature set field1(core::int* _) → void;
abstract member-signature set field2(core::int* _) → void;
- abstract member-signature set property5(core::int* _) → void;
+ abstract forwarding-stub member-signature set property5(core::int* value) → void;
abstract member-signature set setter2(core::int* value) → void;
- abstract member-signature set property1(core::int* value) → void;
+ abstract forwarding-stub member-signature set property1(core::int* value) → void;
abstract member-signature set property2(core::int* value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.transformed.expect
index a926f8b..6208ce9 100644
--- a/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/member_inheritance_from_opt_in.dart.weak.transformed.expect
@@ -43,30 +43,30 @@
get property4() → core::int*
return 0;
set property4(core::int* value) → void {}
- abstract member-signature get property6() → core::int*;
+ abstract forwarding-stub member-signature get property6() → core::int*;
abstract member-signature get getter1() → core::int*;
abstract member-signature get field1() → core::int*;
- abstract member-signature get field2() → core::int*;
- abstract member-signature get getter2() → core::int*;
+ abstract forwarding-stub member-signature get field2() → core::int*;
+ abstract forwarding-stub member-signature get getter2() → core::int*;
abstract member-signature method method5a(core::int* a, core::int* b) → core::int*;
abstract member-signature method method9a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5c([core::int* a = #C2, core::int* b = #C1]) → core::int*;
abstract member-signature get property5() → core::int*;
- abstract member-signature method method2() → core::int*;
+ abstract forwarding-stub member-signature method method2() → core::int*;
abstract member-signature method method7a(core::int* a, {core::int* b = #C1}) → core::int*;
abstract member-signature method method5b(core::int* a, [core::int* b = #C1]) → core::int*;
abstract member-signature method method9b({core::int* a = #C1, core::int* b = #C1}) → core::int*;
abstract member-signature method method1() → core::int*;
abstract member-signature get property1() → core::int*;
- abstract member-signature get property2() → core::int*;
+ abstract forwarding-stub member-signature get property2() → core::int*;
abstract member-signature method method7b({core::int* a = #C2, core::int* b = #C1}) → core::int*;
- abstract member-signature set setter1(core::int* value) → void;
+ abstract forwarding-stub member-signature set setter1(core::int* value) → void;
abstract member-signature set property6(core::int* _) → void;
- abstract member-signature set field1(core::int* _) → void;
+ abstract forwarding-stub member-signature set field1(core::int* _) → void;
abstract member-signature set field2(core::int* _) → void;
- abstract member-signature set property5(core::int* _) → void;
+ abstract forwarding-stub member-signature set property5(core::int* value) → void;
abstract member-signature set setter2(core::int* value) → void;
- abstract member-signature set property1(core::int* value) → void;
+ abstract forwarding-stub member-signature set property1(core::int* value) → void;
abstract member-signature set property2(core::int* value) → void;
}
static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
index cd4124b..2fce215 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.expect
@@ -133,7 +133,7 @@
: super self2::A::•()
;
}
-static field core::List<core::String?>* l = <core::String?>[];
+static field core::List<core::String?>* l = <core::String*>[];
static field core::String? s = null;
static field core::String* t = self2::s!;
static field core::int* field = 42;
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
index cd4124b..2fce215 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.strong.transformed.expect
@@ -133,7 +133,7 @@
: super self2::A::•()
;
}
-static field core::List<core::String?>* l = <core::String?>[];
+static field core::List<core::String?>* l = <core::String*>[];
static field core::String? s = null;
static field core::String* t = self2::s!;
static field core::int* field = 42;
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
index cd4124b..2fce215 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.expect
@@ -133,7 +133,7 @@
: super self2::A::•()
;
}
-static field core::List<core::String?>* l = <core::String?>[];
+static field core::List<core::String?>* l = <core::String*>[];
static field core::String? s = null;
static field core::String* t = self2::s!;
static field core::int* field = 42;
diff --git a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
index cd4124b..2fce215 100644
--- a/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/opt_out.dart.weak.transformed.expect
@@ -133,7 +133,7 @@
: super self2::A::•()
;
}
-static field core::List<core::String?>* l = <core::String?>[];
+static field core::List<core::String?>* l = <core::String*>[];
static field core::String? s = null;
static field core::String* t = self2::s!;
static field core::int* field = 42;
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart b/pkg/front_end/testcases/nnbd/override_checks.dart
new file mode 100644
index 0000000..10e4918
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart
@@ -0,0 +1,30 @@
+// 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 file.
+
+class A<X extends num> {}
+
+class B1 {
+ void set bar(num? value) {}
+ num get baz => 42;
+ void hest(num? value) {}
+}
+
+class B2 extends B1 {
+ num bar = 3.14; // Error in strong mode and Warning in weak mode.
+ num? get baz => null; // Error in strong mode and Warning in weak mode.
+ void hest(num value) {} // Error in strong mode and Warning in weak mode.
+}
+
+class C1 {
+ factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+}
+
+class C2<X extends int> implements C1 {}
+
+class D {
+ D.foo(num x);
+ factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+}
+
+main() {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect
new file mode 100644
index 0000000..6ca32e4
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.outline.expect
@@ -0,0 +1,86 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:14: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:16:17: Error: The parameter 'value' of the method 'B2.hest' has type 'num', which does not match the corresponding type, 'num?', in the overridden method, 'B1.hest'.
+// Change to a supertype of 'num?', or, for a covariant parameter, a subtype.
+// void hest(num value) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:10:8: Context: This is the overridden method ('hest').
+// void hest(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:15:12: Error: The return type of the method 'B2.baz' is 'num?', which does not match the return type, 'num', of the overridden method, 'B1.baz'.
+// Change to a subtype of 'num'.
+// num? get baz => null; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:9:11: Context: This is the overridden method ('baz').
+// num get baz => 42;
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:14:7: Error: The field 'B2.bar' has type 'num', which does not match the corresponding type, 'num?', in the overridden setter, 'B1.bar'.
+// num bar = 3.14; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:8:12: Context: This is the overridden method ('bar').
+// void set bar(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:16: Error: The type 'int?' doesn't extend 'int'.
+// Try using a different type as argument.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:27:27: Error: The constructor function type 'D Function(num)' isn't a subtype of 'D Function(num?)'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/override_checks.dart'.
+// factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ ;
+}
+class B1 extends core::Object {
+ synthetic constructor •() → self::B1
+ ;
+ set bar(core::num? value) → void
+ ;
+ get baz() → core::num
+ ;
+ method hest(core::num? value) → void
+ ;
+}
+class B2 extends self::B1 {
+ field core::num bar;
+ synthetic constructor •() → self::B2
+ ;
+ get baz() → core::num?
+ ;
+ method hest(core::num value) → void
+ ;
+}
+class C1 extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+ static factory •() → self::C1
+ let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
+}
+class C2<X extends core::int = core::int> extends core::Object implements self::C1 {
+ synthetic constructor •() → self::C2<self::C2::X>
+ ;
+}
+class D extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+ constructor foo(core::num x) → self::D
+ ;
+ static factory bar(core::num? x) → self::D
+ let dynamic #redirecting_factory = self::D::foo in invalid-expression;
+}
+static method main() → dynamic
+ ;
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect
new file mode 100644
index 0000000..a2a15d0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:14: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:16:17: Error: The parameter 'value' of the method 'B2.hest' has type 'num', which does not match the corresponding type, 'num?', in the overridden method, 'B1.hest'.
+// Change to a supertype of 'num?', or, for a covariant parameter, a subtype.
+// void hest(num value) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:10:8: Context: This is the overridden method ('hest').
+// void hest(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:15:12: Error: The return type of the method 'B2.baz' is 'num?', which does not match the return type, 'num', of the overridden method, 'B1.baz'.
+// Change to a subtype of 'num'.
+// num? get baz => null; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:9:11: Context: This is the overridden method ('baz').
+// num get baz => 42;
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:14:7: Error: The field 'B2.bar' has type 'num', which does not match the corresponding type, 'num?', in the overridden setter, 'B1.bar'.
+// num bar = 3.14; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:8:12: Context: This is the overridden method ('bar').
+// void set bar(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:16: Error: The type 'int?' doesn't extend 'int'.
+// Try using a different type as argument.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:27:27: Error: The constructor function type 'D Function(num)' isn't a subtype of 'D Function(num?)'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/override_checks.dart'.
+// factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B1 extends core::Object {
+ synthetic constructor •() → self::B1
+ : super core::Object::•()
+ ;
+ set bar(core::num? value) → void {}
+ get baz() → core::num
+ return 42;
+ method hest(core::num? value) → void {}
+}
+class B2 extends self::B1 {
+ field core::num bar = 3.14;
+ synthetic constructor •() → self::B2
+ : super self::B1::•()
+ ;
+ get baz() → core::num?
+ return null;
+ method hest(core::num value) → void {}
+}
+class C1 extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+ static factory •() → self::C1
+ let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
+}
+class C2<X extends core::int = core::int> extends core::Object implements self::C1 {
+ synthetic constructor •() → self::C2<self::C2::X>
+ : super core::Object::•()
+ ;
+}
+class D extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+ constructor foo(core::num x) → self::D
+ : super core::Object::•()
+ ;
+ static factory bar(core::num? x) → self::D
+ let dynamic #redirecting_factory = self::D::foo in invalid-expression;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect
new file mode 100644
index 0000000..3ddcd06
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.strong.transformed.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:14: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:16:17: Error: The parameter 'value' of the method 'B2.hest' has type 'num', which does not match the corresponding type, 'num?', in the overridden method, 'B1.hest'.
+// Change to a supertype of 'num?', or, for a covariant parameter, a subtype.
+// void hest(num value) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:10:8: Context: This is the overridden method ('hest').
+// void hest(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:15:12: Error: The return type of the method 'B2.baz' is 'num?', which does not match the return type, 'num', of the overridden method, 'B1.baz'.
+// Change to a subtype of 'num'.
+// num? get baz => null; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:9:11: Context: This is the overridden method ('baz').
+// num get baz => 42;
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:14:7: Error: The field 'B2.bar' has type 'num', which does not match the corresponding type, 'num?', in the overridden setter, 'B1.bar'.
+// num bar = 3.14; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:8:12: Context: This is the overridden method ('bar').
+// void set bar(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:16: Error: The type 'int?' doesn't extend 'int'.
+// Try using a different type as argument.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:27:27: Error: The constructor function type 'D Function(num)' isn't a subtype of 'D Function(num?)'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/override_checks.dart'.
+// factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B1 extends core::Object {
+ synthetic constructor •() → self::B1
+ : super core::Object::•()
+ ;
+ set bar(core::num? value) → void {}
+ get baz() → core::num
+ return 42;
+ method hest(core::num? value) → void {}
+}
+class B2 extends self::B1 {
+ field core::num bar = 3.14;
+ synthetic constructor •() → self::B2
+ : super self::B1::•()
+ ;
+ get baz() → core::num?
+ return null;
+ method hest(core::num value) → void {}
+}
+class C1 extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+ static factory •() → self::C1
+ let<BottomType> #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
+}
+class C2<X extends core::int = core::int> extends core::Object implements self::C1 {
+ synthetic constructor •() → self::C2<self::C2::X>
+ : super core::Object::•()
+ ;
+}
+class D extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+ constructor foo(core::num x) → self::D
+ : super core::Object::•()
+ ;
+ static factory bar(core::num? x) → self::D
+ let<BottomType> #redirecting_factory = self::D::foo in invalid-expression;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect
new file mode 100644
index 0000000..ffb08e6
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:14: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:16:17: Warning: The parameter 'value' of the method 'B2.hest' has type 'num', which does not match the corresponding type, 'num?', in the overridden method, 'B1.hest'.
+// Change to a supertype of 'num?', or, for a covariant parameter, a subtype.
+// void hest(num value) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:10:8: Context: This is the overridden method ('hest').
+// void hest(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:15:12: Warning: The return type of the method 'B2.baz' is 'num?', which does not match the return type, 'num', of the overridden method, 'B1.baz'.
+// Change to a subtype of 'num'.
+// num? get baz => null; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:9:11: Context: This is the overridden method ('baz').
+// num get baz => 42;
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:14:7: Warning: The field 'B2.bar' has type 'num', which does not match the corresponding type, 'num?', in the overridden setter, 'B1.bar'.
+// num bar = 3.14; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:8:12: Context: This is the overridden method ('bar').
+// void set bar(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:16: Warning: The type 'int?' doesn't extend 'int'.
+// Try using a different type as argument.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:27:27: Warning: The constructor function type 'D Function(num)' isn't a subtype of 'D Function(num?)'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/override_checks.dart'.
+// factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B1 extends core::Object {
+ synthetic constructor •() → self::B1
+ : super core::Object::•()
+ ;
+ set bar(core::num? value) → void {}
+ get baz() → core::num
+ return 42;
+ method hest(core::num? value) → void {}
+}
+class B2 extends self::B1 {
+ field core::num bar = 3.14;
+ synthetic constructor •() → self::B2
+ : super self::B1::•()
+ ;
+ get baz() → core::num?
+ return null;
+ method hest(core::num value) → void {}
+}
+class C1 extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+ static factory •() → self::C1
+ let dynamic #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
+}
+class C2<X extends core::int = core::int> extends core::Object implements self::C1 {
+ synthetic constructor •() → self::C2<self::C2::X>
+ : super core::Object::•()
+ ;
+}
+class D extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+ constructor foo(core::num x) → self::D
+ : super core::Object::•()
+ ;
+ static factory bar(core::num? x) → self::D
+ let dynamic #redirecting_factory = self::D::foo in invalid-expression;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect
new file mode 100644
index 0000000..7042115
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/override_checks.dart.weak.transformed.expect
@@ -0,0 +1,87 @@
+library /*isNonNullableByDefault*/;
+//
+// Problems in library:
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:14: Error: A function declaration needs an explicit list of parameters.
+// Try adding a parameter list to the function declaration.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:16:17: Warning: The parameter 'value' of the method 'B2.hest' has type 'num', which does not match the corresponding type, 'num?', in the overridden method, 'B1.hest'.
+// Change to a supertype of 'num?', or, for a covariant parameter, a subtype.
+// void hest(num value) {} // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:10:8: Context: This is the overridden method ('hest').
+// void hest(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:15:12: Warning: The return type of the method 'B2.baz' is 'num?', which does not match the return type, 'num', of the overridden method, 'B1.baz'.
+// Change to a subtype of 'num'.
+// num? get baz => null; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:9:11: Context: This is the overridden method ('baz').
+// num get baz => 42;
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:14:7: Warning: The field 'B2.bar' has type 'num', which does not match the corresponding type, 'num?', in the overridden setter, 'B1.bar'.
+// num bar = 3.14; // Error in strong mode and Warning in weak mode.
+// ^
+// pkg/front_end/testcases/nnbd/override_checks.dart:8:12: Context: This is the overridden method ('bar').
+// void set bar(num? value) {}
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:20:16: Warning: The type 'int?' doesn't extend 'int'.
+// Try using a different type as argument.
+// factory C1 = C2<int?>; // Error in strong mode and Warning in weak mode.
+// ^
+//
+// pkg/front_end/testcases/nnbd/override_checks.dart:27:27: Warning: The constructor function type 'D Function(num)' isn't a subtype of 'D Function(num?)'.
+// - 'D' is from 'pkg/front_end/testcases/nnbd/override_checks.dart'.
+// factory D.bar(num? x) = D.foo; // Error in strong mode and Warning in weak mode.
+// ^
+//
+import self as self;
+import "dart:core" as core;
+
+class A<X extends core::num = core::num> extends core::Object {
+ synthetic constructor •() → self::A<self::A::X>
+ : super core::Object::•()
+ ;
+}
+class B1 extends core::Object {
+ synthetic constructor •() → self::B1
+ : super core::Object::•()
+ ;
+ set bar(core::num? value) → void {}
+ get baz() → core::num
+ return 42;
+ method hest(core::num? value) → void {}
+}
+class B2 extends self::B1 {
+ field core::num bar = 3.14;
+ synthetic constructor •() → self::B2
+ : super self::B1::•()
+ ;
+ get baz() → core::num?
+ return null;
+ method hest(core::num value) → void {}
+}
+class C1 extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::C1::•]/*isNullableByDefault*/;
+ static factory •() → self::C1
+ let<BottomType> #redirecting_factory = self::C2::• in let core::int? #typeArg0 = null in invalid-expression;
+}
+class C2<X extends core::int = core::int> extends core::Object implements self::C1 {
+ synthetic constructor •() → self::C2<self::C2::X>
+ : super core::Object::•()
+ ;
+}
+class D extends core::Object {
+ static field dynamic _redirecting# = <dynamic>[self::D::bar]/*isNullableByDefault*/;
+ constructor foo(core::num x) → self::D
+ : super core::Object::•()
+ ;
+ static factory bar(core::num? x) → self::D
+ let<BottomType> #redirecting_factory = self::D::foo in invalid-expression;
+}
+static method main() → dynamic {}
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect
index f35cdbd..9ddd160 100644
--- a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.expect
@@ -54,7 +54,7 @@
}
static method test(self::Class? c) → dynamic {
let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
- self::throwsInStrong(() → core::int => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ self::throwsInStrong(() → core::int? => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
throwsInStrong(() => c?.field + 2); // error
^" in (let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class}.{self::Class::field}).{core::num::+}(2));
let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = #t4.{self::Class::field}.{core::num::+}(1) in let final void #t6 = #t4.{self::Class::field} = #t5 in #t5;
@@ -68,7 +68,7 @@
throwsInStrong(() => -c?.field); // error
^" in (let final self::Class? #t11 = c in #t11.{core::Object::==}(null) ?{core::int?} null : #t11{self::Class}.{self::Class::field}).{core::int::unary-}());
let final self::Class? #t12 = c in #t12.{core::Object::==}(null) ?{core::bool?} null : #t12{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
- self::throwsInStrong(() → core::int => let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ self::throwsInStrong(() → core::int? => let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
throwsInStrong(() => c?.next[0] + 2); // error
^" in (let final self::Class? #t14 = c in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
let final self::Class? #t15 = c in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::next} in let final core::int #t17 = 0 in let final core::int #t18 = #t16.{self::Class::[]}(#t17).{core::num::+}(1) in let final void #t19 = #t16.{self::Class::[]=}(#t17, #t18) in #t18;
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect
index f35cdbd..9ddd160 100644
--- a/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.strong.transformed.expect
@@ -54,7 +54,7 @@
}
static method test(self::Class? c) → dynamic {
let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
- self::throwsInStrong(() → core::int => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ self::throwsInStrong(() → core::int? => let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:18:33: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
throwsInStrong(() => c?.field + 2); // error
^" in (let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : #t3{self::Class}.{self::Class::field}).{core::num::+}(2));
let final self::Class? #t4 = c in #t4.{core::Object::==}(null) ?{core::int?} null : let final core::int #t5 = #t4.{self::Class::field}.{core::num::+}(1) in let final void #t6 = #t4.{self::Class::field} = #t5 in #t5;
@@ -68,7 +68,7 @@
throwsInStrong(() => -c?.field); // error
^" in (let final self::Class? #t11 = c in #t11.{core::Object::==}(null) ?{core::int?} null : #t11{self::Class}.{self::Class::field}).{core::int::unary-}());
let final self::Class? #t12 = c in #t12.{core::Object::==}(null) ?{core::bool?} null : #t12{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
- self::throwsInStrong(() → core::int => let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
+ self::throwsInStrong(() → core::int? => let final<BottomType> #t13 = invalid-expression "pkg/front_end/testcases/nnbd/shorting_stop.dart:25:35: Error: Operator '+' cannot be called on 'int?' because it is potentially null.
throwsInStrong(() => c?.next[0] + 2); // error
^" in (let final self::Class? #t14 = c in #t14.{core::Object::==}(null) ?{core::int?} null : #t14{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
let final self::Class? #t15 = c in #t15.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t16 = #t15{self::Class}.{self::Class::next} in let final core::int #t17 = 0 in let final core::int #t18 = #t16.{self::Class::[]}(#t17).{core::num::+}(1) in let final void #t19 = #t16.{self::Class::[]=}(#t17, #t18) in #t18;
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect
index e32de91..0c83c79 100644
--- a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.expect
@@ -54,13 +54,13 @@
}
static method test(self::Class? c) → dynamic {
let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
- self::throwsInStrong(() → core::int => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
+ self::throwsInStrong(() → core::int? => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : let final core::int #t4 = #t3.{self::Class::field}.{core::num::+}(1) in let final void #t5 = #t3.{self::Class::field} = #t4 in #t4;
let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{core::int?} null : #t6.{self::Class::field} = #t6.{self::Class::field}.{core::num::+}(1);
self::throwsInStrong(() → core::int => (let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::next}).{self::Class::field});
self::throwsInStrong(() → core::int => (let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{core::int?} null : #t8{self::Class}.{self::Class::field}).{core::int::unary-}());
let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{core::bool?} null : #t9{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
- self::throwsInStrong(() → core::int => (let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+ self::throwsInStrong(() → core::int? => (let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
let final self::Class? #t11 = c in #t11.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t12 = #t11{self::Class}.{self::Class::next} in let final core::int #t13 = 0 in let final core::int #t14 = #t12.{self::Class::[]}(#t13).{core::num::+}(1) in let final void #t15 = #t12.{self::Class::[]=}(#t13, #t14) in #t14;
let final self::Class? #t16 = c in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t17 = #t16{self::Class}.{self::Class::next} in let final core::int #t18 = 0 in #t17.{self::Class::[]=}(#t18, #t17.{self::Class::[]}(#t18).{core::num::+}(1));
self::throwsInStrong(() → core::bool => (let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{core::int?} null : #t19{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
diff --git a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect
index e32de91..0c83c79 100644
--- a/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd/shorting_stop.dart.weak.transformed.expect
@@ -54,13 +54,13 @@
}
static method test(self::Class? c) → dynamic {
let final self::Class? #t1 = c in #t1.{core::Object::==}(null) ?{core::int?} null : #t1{self::Class}.{self::Class::next}.{self::Class::field};
- self::throwsInStrong(() → core::int => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
+ self::throwsInStrong(() → core::int? => (let final self::Class? #t2 = c in #t2.{core::Object::==}(null) ?{core::int?} null : #t2{self::Class}.{self::Class::field}).{core::num::+}(2));
let final self::Class? #t3 = c in #t3.{core::Object::==}(null) ?{core::int?} null : let final core::int #t4 = #t3.{self::Class::field}.{core::num::+}(1) in let final void #t5 = #t3.{self::Class::field} = #t4 in #t4;
let final self::Class? #t6 = c in #t6.{core::Object::==}(null) ?{core::int?} null : #t6.{self::Class::field} = #t6.{self::Class::field}.{core::num::+}(1);
self::throwsInStrong(() → core::int => (let final self::Class? #t7 = c in #t7.{core::Object::==}(null) ?{self::Class?} null : #t7{self::Class}.{self::Class::next}).{self::Class::field});
self::throwsInStrong(() → core::int => (let final self::Class? #t8 = c in #t8.{core::Object::==}(null) ?{core::int?} null : #t8{self::Class}.{self::Class::field}).{core::int::unary-}());
let final self::Class? #t9 = c in #t9.{core::Object::==}(null) ?{core::bool?} null : #t9{self::Class}.{self::Class::next}.{self::Class::[]}(0).{core::int::isEven};
- self::throwsInStrong(() → core::int => (let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
+ self::throwsInStrong(() → core::int? => (let final self::Class? #t10 = c in #t10.{core::Object::==}(null) ?{core::int?} null : #t10{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::num::+}(2));
let final self::Class? #t11 = c in #t11.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t12 = #t11{self::Class}.{self::Class::next} in let final core::int #t13 = 0 in let final core::int #t14 = #t12.{self::Class::[]}(#t13).{core::num::+}(1) in let final void #t15 = #t12.{self::Class::[]=}(#t13, #t14) in #t14;
let final self::Class? #t16 = c in #t16.{core::Object::==}(null) ?{core::int?} null : let final self::Class #t17 = #t16{self::Class}.{self::Class::next} in let final core::int #t18 = 0 in #t17.{self::Class::[]=}(#t18, #t17.{self::Class::[]}(#t18).{core::num::+}(1));
self::throwsInStrong(() → core::bool => (let final self::Class? #t19 = c in #t19.{core::Object::==}(null) ?{core::int?} null : #t19{self::Class}.{self::Class::next}.{self::Class::[]}(0)).{core::int::isEven});
diff --git a/pkg/front_end/testcases/text_serialization.status b/pkg/front_end/testcases/text_serialization.status
index 9d55251..2b9be20 100644
--- a/pkg/front_end/testcases/text_serialization.status
+++ b/pkg/front_end/testcases/text_serialization.status
@@ -1221,6 +1221,7 @@
new_const_insertion/simple: TextSerializationFailure # Was: Pass
nnbd/assign_type_variable: TextSerializationFailure
nnbd/assignability: TextSerializationFailure
+nnbd/bounds_checks: TextSerializationFailure
nnbd/call: TextSerializationFailure
nnbd/constants: TextSerializationFailure
nnbd/definite_assignment_and_completion: TextSerializationFailure
@@ -1233,6 +1234,7 @@
nnbd/infer_from_opt_in: TextSerializationFailure
nnbd/infer_from_opt_out: TextSerializationFailure
nnbd/infer_if_null: TextSerializationFailure
+nnbd/infer_in_legacy_from_opted_in: TextSerializationFailure
nnbd/inheritance_from_opt_in: TypeCheckError
nnbd/inheritance_from_opt_out: TextSerializationFailure
nnbd/intersection_types: TextSerializationFailure
@@ -1279,6 +1281,7 @@
nnbd/nullable_param: TextSerializationFailure
nnbd/nullable_receiver: TextSerializationFailure
nnbd/opt_out: TextSerializationFailure
+nnbd/override_checks: TextSerializationFailure
nnbd/platform_definite_assignment/main: TextSerializationFailure
nnbd/platform_optional_parameters/main: TextSerializationFailure
nnbd/potentially_non_nullable_field: TextSerializationFailure
diff --git a/pkg/kernel/lib/naive_type_checker.dart b/pkg/kernel/lib/naive_type_checker.dart
index c7d012a..20ee3b5 100644
--- a/pkg/kernel/lib/naive_type_checker.dart
+++ b/pkg/kernel/lib/naive_type_checker.dart
@@ -112,6 +112,8 @@
if (subtype is InvalidType || supertype is InvalidType) {
return true;
}
+ // TODO(dmitryas): Find a way to tell the weak mode from strong mode to use
+ // [SubtypeCheckMode.withNullabilities] where necessary.
return environment.isSubtypeOf(
subtype, supertype, SubtypeCheckMode.ignoringNullabilities);
}
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index a92c8d3..03e68b4 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -210,12 +210,29 @@
TypeArgumentIssue(
this.index, this.argument, this.typeParameter, this.enclosingType);
+
+ int get hashCode {
+ int hash = 0x3fffffff & index;
+ hash = 0x3fffffff & (hash * 31 + (hash ^ argument.hashCode));
+ hash = 0x3fffffff & (hash * 31 + (hash ^ typeParameter.hashCode));
+ hash = 0x3fffffff & (hash * 31 + (hash ^ enclosingType.hashCode));
+ return hash;
+ }
+
+ bool operator ==(dynamic other) {
+ assert(other is TypeArgumentIssue);
+ if (other is! TypeArgumentIssue) return false;
+ return index == other.index &&
+ argument == other.argument &&
+ typeParameter == other.typeParameter &&
+ enclosingType == other.enclosingType;
+ }
}
// TODO(dmitryas): Remove [typedefInstantiations] when type arguments passed to
// typedefs are preserved in the Kernel output.
-List<TypeArgumentIssue> findTypeArgumentIssues(
- DartType type, TypeEnvironment typeEnvironment,
+List<TypeArgumentIssue> findTypeArgumentIssues(DartType type,
+ TypeEnvironment typeEnvironment, SubtypeCheckMode subtypeCheckMode,
{bool allowSuperBounded = false}) {
List<TypeParameter> variables;
List<DartType> arguments;
@@ -233,7 +250,8 @@
typeParameters: functionType.typeParameters,
requiredParameterCount: functionType.requiredParameterCount,
typedefType: null);
- typedefRhsResult = findTypeArgumentIssues(cloned, typeEnvironment,
+ typedefRhsResult = findTypeArgumentIssues(
+ cloned, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true);
type = functionType.typedefType;
}
@@ -247,21 +265,25 @@
} else if (type is FunctionType) {
List<TypeArgumentIssue> result = <TypeArgumentIssue>[];
for (TypeParameter parameter in type.typeParameters) {
- result.addAll(findTypeArgumentIssues(parameter.bound, typeEnvironment,
+ result.addAll(findTypeArgumentIssues(
+ parameter.bound, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true) ??
const <TypeArgumentIssue>[]);
}
for (DartType formal in type.positionalParameters) {
- result.addAll(findTypeArgumentIssues(formal, typeEnvironment,
+ result.addAll(findTypeArgumentIssues(
+ formal, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true) ??
const <TypeArgumentIssue>[]);
}
for (NamedType named in type.namedParameters) {
- result.addAll(findTypeArgumentIssues(named.type, typeEnvironment,
+ result.addAll(findTypeArgumentIssues(
+ named.type, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true) ??
const <TypeArgumentIssue>[]);
}
- result.addAll(findTypeArgumentIssues(type.returnType, typeEnvironment,
+ result.addAll(findTypeArgumentIssues(
+ type.returnType, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true) ??
const <TypeArgumentIssue>[]);
return result.isEmpty ? null : result;
@@ -282,16 +304,19 @@
// Generic function types aren't allowed as type arguments either.
result ??= <TypeArgumentIssue>[];
result.add(new TypeArgumentIssue(i, argument, variables[i], type));
- } else if (!typeEnvironment.isSubtypeOf(
- argument,
- substitute(variables[i].bound, substitutionMap),
- SubtypeCheckMode.ignoringNullabilities)) {
+ } else if (variables[i].bound is! InvalidType &&
+ !typeEnvironment.isSubtypeOf(
+ argument,
+ substitute(variables[i].bound, substitutionMap),
+ subtypeCheckMode)) {
+ // If the bound is InvalidType it's not checked, because an error was
+ // reported already at the time of the creation of InvalidType.
result ??= <TypeArgumentIssue>[];
result.add(new TypeArgumentIssue(i, argument, variables[i], type));
}
List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- argument, typeEnvironment,
+ argument, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true);
if (issues != null) {
argumentsResult ??= <TypeArgumentIssue>[];
@@ -330,10 +355,8 @@
result ??= <TypeArgumentIssue>[];
result.add(
new TypeArgumentIssue(i, argumentsToReport[i], variables[i], type));
- } else if (!typeEnvironment.isSubtypeOf(
- argument,
- substitute(variables[i].bound, substitutionMap),
- SubtypeCheckMode.ignoringNullabilities)) {
+ } else if (!typeEnvironment.isSubtypeOf(argument,
+ substitute(variables[i].bound, substitutionMap), subtypeCheckMode)) {
result ??= <TypeArgumentIssue>[];
result.add(
new TypeArgumentIssue(i, argumentsToReport[i], variables[i], type));
@@ -356,6 +379,7 @@
List<TypeParameter> parameters,
List<DartType> arguments,
TypeEnvironment typeEnvironment,
+ SubtypeCheckMode subtypeCheckMode,
{Map<FunctionType, List<DartType>> typedefInstantiations}) {
assert(arguments.length == parameters.length);
List<TypeArgumentIssue> result;
@@ -372,16 +396,14 @@
// Generic function types aren't allowed as type arguments either.
result ??= <TypeArgumentIssue>[];
result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
- } else if (!typeEnvironment.isSubtypeOf(
- argument,
- substitute(parameters[i].bound, substitutionMap),
- SubtypeCheckMode.ignoringNullabilities)) {
+ } else if (!typeEnvironment.isSubtypeOf(argument,
+ substitute(parameters[i].bound, substitutionMap), subtypeCheckMode)) {
result ??= <TypeArgumentIssue>[];
result.add(new TypeArgumentIssue(i, argument, parameters[i], null));
}
List<TypeArgumentIssue> issues = findTypeArgumentIssues(
- argument, typeEnvironment,
+ argument, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true);
if (issues != null) {
result ??= <TypeArgumentIssue>[];