[kernel] Make TypeParameter.bound non-nullable
Change-Id: I31e693a5b77db039c6a2f8ac8ea534ad663ae0ac
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/195988
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
Commit-Queue: Johnni Winther <johnniwinther@google.com>
diff --git a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
index ba03221..93ee6da 100644
--- a/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
+++ b/pkg/front_end/lib/src/fasta/builder/type_variable_builder.dart
@@ -101,7 +101,7 @@
bool needsPostUpdate = false;
Nullability nullability;
if (nullabilityBuilder.isOmitted) {
- if (parameter.bound != null) {
+ if (!identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
nullability = library.isNonNullableByDefault
? TypeParameterType.computeNullabilityFromBound(parameter)
: Nullability.legacy;
@@ -154,7 +154,9 @@
// TODO(jensj): Provide correct notInstanceContext.
DartType objectType =
object.buildType(library, library.nullableBuilder, null, null);
- parameter.bound ??= bound?.build(library) ?? objectType;
+ if (identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
+ parameter.bound = bound?.build(library) ?? objectType;
+ }
// If defaultType is not set, initialize it to dynamic, unless the bound is
// explicitly specified as Object, in which case defaultType should also be
// Object. This makes sure instantiation of generic function types with an
diff --git a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
index 2a81180..be667a7 100644
--- a/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/invalid_type.dart
@@ -79,7 +79,7 @@
bool visitFunctionType(FunctionType node, Set<TypedefType> visitedTypedefs) {
if (node.returnType.accept1(this, visitedTypedefs)) return true;
for (TypeParameter typeParameter in node.typeParameters) {
- if (typeParameter.bound!.accept1(this, visitedTypedefs)) return true;
+ if (typeParameter.bound.accept1(this, visitedTypedefs)) return true;
// TODO(dmitryas): Check defaultTypes as well if they cause cascading
// errors.
}
diff --git a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
index 3057286..615343c 100644
--- a/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
+++ b/pkg/front_end/lib/src/fasta/source/source_type_alias_builder.dart
@@ -179,7 +179,7 @@
new List<DartType>.filled(typedef.typeParameters.length, null);
for (int i = 0; i < bounds.length; ++i) {
bounds[i] = typedef.typeParameters[i].bound;
- if (bounds[i] == null) {
+ if (identical(bounds[i], TypeParameter.unsetBoundSentinel)) {
typedef.typeParameters[i].bound = const DynamicType();
}
}
@@ -188,7 +188,7 @@
TypedefType result =
new TypedefType(typedef, clientLibrary.nonNullable, asTypeArguments);
for (int i = 0; i < bounds.length; ++i) {
- if (bounds[i] == null) {
+ if (identical(bounds[i], TypeParameter.unsetBoundSentinel)) {
// If the bound is not assigned yet, put the corresponding
// type-parameter type into the list for the nullability re-computation.
// At this point, [parent] should be a [SourceLibraryBuilder] because
diff --git a/pkg/kernel/lib/ast.dart b/pkg/kernel/lib/ast.dart
index a473048..2c32b9c 100644
--- a/pkg/kernel/lib/ast.dart
+++ b/pkg/kernel/lib/ast.dart
@@ -10886,8 +10886,8 @@
}
for (int index = 0; index < typeParameters.length; index++) {
if (!typeParameters[index]
- .bound!
- .equals(other.typeParameters[index].bound!, assumptions)) {
+ .bound
+ .equals(other.typeParameters[index].bound, assumptions)) {
return false;
}
}
@@ -11571,7 +11571,7 @@
}
/// Returns the bound of the type parameter, accounting for promotions.
- DartType get bound => (promotedBound ?? parameter.bound)!;
+ DartType get bound => promotedBound ?? parameter.bound;
/// Nullability of the type, calculated from its parts.
///
@@ -11621,8 +11621,8 @@
// non-nullable types can be passed in for the type parameter, making the
// corresponding type parameter types 'undetermined.' Otherwise, the
// nullability matches that of the bound.
- DartType? bound = typeParameter.bound;
- if (bound == null) {
+ DartType bound = typeParameter.bound;
+ if (identical(bound, TypeParameter.unsetBoundSentinel)) {
throw new StateError("Can't compute nullability from an absent bound.");
}
@@ -11632,7 +11632,7 @@
// other ways for such a dependency to exist, they should be checked here.
bool nullabilityDependsOnItself = false;
{
- DartType? type = typeParameter.bound;
+ DartType type = typeParameter.bound;
while (type is FutureOrType) {
type = type.typeArgument;
}
@@ -11971,12 +11971,17 @@
String? name; // Cosmetic name.
+ /// Sentinel value used for the [bound] that has not yet been computed. This
+ /// is needed to make the [bound] field non-nullable while supporting
+ /// recursive bounds.
+ static final DartType unsetBoundSentinel = new InvalidType();
+
/// The bound on the type variable.
///
- /// Should not be null except temporarily during IR construction. Should
- /// be set to the root class for type parameters without an explicit bound.
- // TODO(johnniwinther): Can we make this late non-nullable?
- DartType? bound;
+ /// This is set to [unsetBoundSentinel] temporarily during IR construction.
+ /// This is set to the `Object?` for type parameters without an explicit
+ /// bound.
+ DartType bound;
/// The default value of the type variable. It is used to provide the
/// corresponding missing type argument in type annotations and as the
@@ -12002,7 +12007,8 @@
static const int legacyCovariantSerializationMarker = 4;
- TypeParameter([this.name, this.bound, this.defaultType]);
+ TypeParameter([this.name, DartType? bound, this.defaultType])
+ : bound = bound ?? unsetBoundSentinel;
// Must match serialized bit positions.
static const int FlagGenericCovariantImpl = 1 << 0;
@@ -12039,15 +12045,16 @@
@override
void visitChildren(Visitor v) {
visitList(annotations, v);
- bound?.accept(v);
+ bound.accept(v);
defaultType?.accept(v);
}
@override
void transformChildren(Transformer v) {
v.transformList(annotations, this);
+ // ignore: unnecessary_null_comparison
if (bound != null) {
- bound = v.visitDartType(bound!);
+ bound = v.visitDartType(bound);
}
if (defaultType != null) {
defaultType = v.visitDartType(defaultType!);
@@ -12057,13 +12064,9 @@
@override
void transformOrRemoveChildren(RemovingTransformer v) {
v.transformExpressionList(annotations, this);
+ // ignore: unnecessary_null_comparison
if (bound != null) {
- DartType newBound = v.visitDartType(bound!, dummyDartType);
- if (identical(newBound, dummyDartType)) {
- bound = null;
- } else {
- bound = newBound;
- }
+ bound = v.visitDartType(bound, cannotRemoveSentinel);
}
if (defaultType != null) {
DartType newDefaultType = v.visitDartType(defaultType!, dummyDartType);
diff --git a/pkg/kernel/lib/binary/ast_to_binary.dart b/pkg/kernel/lib/binary/ast_to_binary.dart
index 3805110..6e4052a 100644
--- a/pkg/kernel/lib/binary/ast_to_binary.dart
+++ b/pkg/kernel/lib/binary/ast_to_binary.dart
@@ -2400,7 +2400,7 @@
writeByte(node.variance);
}
writeStringReference(node.name ?? '');
- writeNode(node.bound!);
+ writeNode(node.bound);
// TODO(johnniwinther): Make this non-optional.
writeOptionalNode(node.defaultType);
}
diff --git a/pkg/kernel/lib/clone.dart b/pkg/kernel/lib/clone.dart
index a399b3a..29a21e3 100644
--- a/pkg/kernel/lib/clone.dart
+++ b/pkg/kernel/lib/clone.dart
@@ -509,7 +509,7 @@
visitTypeParameter(TypeParameter node) {
TypeParameter newNode = typeParams[node]!;
- newNode.bound = visitType(node.bound!);
+ newNode.bound = visitType(node.bound);
if (node.defaultType != null) {
newNode.defaultType = visitType(node.defaultType!);
}
diff --git a/pkg/kernel/lib/core_types.dart b/pkg/kernel/lib/core_types.dart
index 63ad64c..4123eec 100644
--- a/pkg/kernel/lib/core_types.dart
+++ b/pkg/kernel/lib/core_types.dart
@@ -1180,7 +1180,7 @@
// BOTTOM(X extends T) is true iff BOTTOM(T).
if (type is TypeParameterType && type.isPotentiallyNonNullable) {
assert(type.promotedBound == null);
- return isBottom(type.parameter.bound!);
+ return isBottom(type.parameter.bound);
}
return false;
diff --git a/pkg/kernel/lib/src/bounds_checks.dart b/pkg/kernel/lib/src/bounds_checks.dart
index 17b0a06..47b03e6 100644
--- a/pkg/kernel/lib/src/bounds_checks.dart
+++ b/pkg/kernel/lib/src/bounds_checks.dart
@@ -87,7 +87,7 @@
void visitFunctionType(FunctionType node) {
for (TypeParameter typeParameter in node.typeParameters) {
- typeParameter.bound!.accept(this);
+ typeParameter.bound.accept(this);
typeParameter.defaultType?.accept(this);
}
for (DartType parameter in node.positionalParameters) {
@@ -164,9 +164,9 @@
List<DartType> bounds =
new List<DartType>.filled(typeParameters.length, dummyDartType);
for (int i = 0; i < typeParameters.length; i++) {
- DartType? bound = typeParameters[i].bound;
+ DartType bound = typeParameters[i].bound;
bool isContravariant = typeParameters[i].variance == Variance.contravariant;
- if (bound == null) {
+ if (identical(bound, TypeParameter.unsetBoundSentinel)) {
bound = isNonNullableByDefault && isContravariant
? const NeverType.nonNullable()
: const DynamicType();
@@ -326,7 +326,7 @@
for (TypeParameter parameter in type.typeParameters) {
result.addAll(findTypeArgumentIssues(
- parameter.bound!, typeEnvironment, subtypeCheckMode,
+ parameter.bound, typeEnvironment, subtypeCheckMode,
allowSuperBounded: true,
isNonNullableByDefault: isNonNullableByDefault,
areGenericArgumentsAllowed: areGenericArgumentsAllowed));
@@ -380,7 +380,7 @@
result.add(new TypeArgumentIssue(i, argument, variables[i], type,
isGenericTypeAsArgumentIssue: true));
} else if (variables[i].bound is! InvalidType) {
- DartType bound = substitute(variables[i].bound!, substitutionMap);
+ DartType bound = substitute(variables[i].bound, substitutionMap);
if (!isNonNullableByDefault) {
bound = legacyErasure(bound);
}
@@ -434,7 +434,7 @@
// Generic function types aren't allowed as type arguments either.
isCorrectSuperBounded = false;
} else if (!typeEnvironment.isSubtypeOf(argument,
- substitute(variables[i].bound!, substitutionMap), subtypeCheckMode)) {
+ substitute(variables[i].bound, substitutionMap), subtypeCheckMode)) {
isCorrectSuperBounded = false;
}
}
@@ -499,7 +499,7 @@
result.add(new TypeArgumentIssue(i, argument, parameters[i], null,
isGenericTypeAsArgumentIssue: true));
} else if (parameters[i].bound is! InvalidType) {
- DartType bound = substitute(parameters[i].bound!, substitutionMap);
+ DartType bound = substitute(parameters[i].bound, substitutionMap);
if (!isNonNullableByDefault) {
bound = legacyErasure(bound);
}
@@ -817,7 +817,7 @@
// variance of [typeParameter] in the entire type invariant. The
// invocation of the visitor below is made to simply figure out if
// [typeParameter] occurs in the bound.
- if (computeVariance(typeParameter, functionTypeParameter.bound!,
+ if (computeVariance(typeParameter, functionTypeParameter.bound,
computedVariances: computedVariances) !=
Variance.unrelated) {
result = Variance.invariant;
diff --git a/pkg/kernel/lib/src/merge_visitor.dart b/pkg/kernel/lib/src/merge_visitor.dart
index b626fa1..d18083c 100644
--- a/pkg/kernel/lib/src/merge_visitor.dart
+++ b/pkg/kernel/lib/src/merge_visitor.dart
@@ -75,7 +75,7 @@
for (int i = 0; i < newTypeParameters.length; i++) {
DartType? newBound =
- mergeTypes(a.typeParameters[i].bound!, b.typeParameters[i].bound!);
+ mergeTypes(a.typeParameters[i].bound, b.typeParameters[i].bound);
if (newBound == null) {
return null;
}
diff --git a/pkg/kernel/lib/src/norm.dart b/pkg/kernel/lib/src/norm.dart
index 78ab826..0cc5d54 100644
--- a/pkg/kernel/lib/src/norm.dart
+++ b/pkg/kernel/lib/src/norm.dart
@@ -93,7 +93,7 @@
@override
DartType? visitTypeParameterType(TypeParameterType node, int variance) {
if (node.promotedBound == null) {
- DartType bound = node.parameter.bound!;
+ DartType bound = node.parameter.bound;
if (normalizesToNever(bound)) {
DartType result = NeverType.fromNullability(node.nullability);
return result.accept1(this, variance) ?? result;
@@ -118,7 +118,7 @@
assert(!coreTypes.isTop(bound));
return new TypeParameterType(node.parameter, node.declaredNullability);
} else if (bound == coreTypes.objectNonNullableRawType &&
- norm(coreTypes, node.parameter.bound!) ==
+ norm(coreTypes, node.parameter.bound) ==
coreTypes.objectNonNullableRawType) {
return new TypeParameterType(node.parameter, node.declaredNullability);
} else if (identical(bound, node.promotedBound)) {
@@ -143,7 +143,7 @@
return true;
} else if (type is TypeParameterType) {
if (type.promotedBound == null) {
- return normalizesToNever(type.parameter.bound!);
+ return normalizesToNever(type.parameter.bound);
} else {
return normalizesToNever(type.promotedBound!);
}
diff --git a/pkg/kernel/lib/src/printer.dart b/pkg/kernel/lib/src/printer.dart
index 5874ca7..cb4b9e6 100644
--- a/pkg/kernel/lib/src/printer.dart
+++ b/pkg/kernel/lib/src/printer.dart
@@ -259,7 +259,7 @@
for (TypeParameter typeParameter in typeParameters) {
_sb.write(comma);
_sb.write(typeParameter.name);
- DartType bound = typeParameter.bound!;
+ DartType bound = typeParameter.bound;
bool isTopObject(DartType type) {
if (type is InterfaceType &&
@@ -401,7 +401,7 @@
}
_sb.write(node.typeParameters[index].name);
_sb.write(' extends ');
- writeType(node.typeParameters[index].bound!);
+ writeType(node.typeParameters[index].bound);
}
_sb.write('>');
}
diff --git a/pkg/kernel/lib/src/replacement_visitor.dart b/pkg/kernel/lib/src/replacement_visitor.dart
index a3db97a2..ced29bc 100644
--- a/pkg/kernel/lib/src/replacement_visitor.dart
+++ b/pkg/kernel/lib/src/replacement_visitor.dart
@@ -24,7 +24,7 @@
// instantiate_to_bound/non_simple_class_parametrized_typedef_cycle
// fails with this.
DartType? newBound = typeParameter.bound
- ?.accept1(this, Variance.combine(variance, Variance.invariant));
+ .accept1(this, Variance.combine(variance, Variance.invariant));
DartType? newDefaultType = typeParameter.defaultType
?.accept1(this, Variance.combine(variance, Variance.invariant));
if (newBound != null || newDefaultType != null) {
@@ -48,7 +48,7 @@
Substitution.fromPairs(node.typeParameters, typeParameterTypes);
for (int i = 0; i < newTypeParameters.length; i++) {
newTypeParameters[i].bound =
- substitution.substituteType(newTypeParameters[i].bound!);
+ substitution.substituteType(newTypeParameters[i].bound);
}
}
diff --git a/pkg/kernel/lib/src/standard_bounds.dart b/pkg/kernel/lib/src/standard_bounds.dart
index 8794dec..81e1974 100644
--- a/pkg/kernel/lib/src/standard_bounds.dart
+++ b/pkg/kernel/lib/src/standard_bounds.dart
@@ -232,7 +232,7 @@
if (s is TypeParameterType && t is TypeParameterType) {
assert(s.promotedBound == null);
assert(t.promotedBound == null);
- return morebottom(s.parameter.bound!, t.parameter.bound!);
+ return morebottom(s.parameter.bound, t.parameter.bound);
}
throw new UnsupportedError("morebottom($s, $t)");
@@ -947,8 +947,8 @@
// TODO(dmitryas): Figure out if a procedure for syntactic equality
// should be used instead.
if (!areMutualSubtypes(
- f.typeParameters[i].bound!,
- substitution.substituteType(g.typeParameters[i].bound!),
+ f.typeParameters[i].bound,
+ substitution.substituteType(g.typeParameters[i].bound),
SubtypeCheckMode.withNullabilities)) {
boundsMatch = false;
}
@@ -1146,8 +1146,8 @@
// TODO(dmitryas): Figure out if a procedure for syntactic
// equality should be used instead.
if (!areMutualSubtypes(
- f.typeParameters[i].bound!,
- substitution.substituteType(g.typeParameters[i].bound!),
+ f.typeParameters[i].bound,
+ substitution.substituteType(g.typeParameters[i].bound),
SubtypeCheckMode.withNullabilities)) {
boundsMatch = false;
}
@@ -1230,12 +1230,12 @@
topFunctionType: coreTypes.functionNonNullableRawType,
unhandledTypeHandler: (type, recursor) => false);
return _getNullabilityAwareStandardUpperBound(
- eliminator.eliminateToGreatest(type1.parameter.bound!),
+ eliminator.eliminateToGreatest(type1.parameter.bound),
type2,
clientLibrary)
.withDeclaredNullability(uniteNullabilities(
type1.declaredNullability,
- uniteNullabilities(type1.parameter.bound!.declaredNullability,
+ uniteNullabilities(type1.parameter.bound.declaredNullability,
type2.declaredNullability)));
} else {
// UP(X1 & B1, T2) =
@@ -1672,14 +1672,14 @@
// we need to replicate that behavior?
return getStandardUpperBound(
Substitution.fromMap({type1.parameter: coreTypes.objectLegacyRawType})
- .substituteType(type1.parameter.bound!),
+ .substituteType(type1.parameter.bound),
type2,
clientLibrary);
} else if (type2 is TypeParameterType) {
return getStandardUpperBound(
type1,
Substitution.fromMap({type2.parameter: coreTypes.objectLegacyRawType})
- .substituteType(type2.parameter.bound!),
+ .substituteType(type2.parameter.bound),
clientLibrary);
} else {
// We should only be called when at least one of the types is a
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 0c4abbc..550417c 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -357,7 +357,7 @@
IsSubtypeOf isTypeParameterRelated(
TypeParameterType s, InterfaceType t, Types types) {
return types
- .performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
+ .performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
@@ -437,7 +437,7 @@
TypeParameter sTypeVariable = sTypeVariables[i];
TypeParameter tTypeVariable = tTypeVariables[i];
result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
- sTypeVariable.bound!, tTypeVariable.bound!));
+ sTypeVariable.bound, tTypeVariable.bound));
typeVariableSubstitution.add(new TypeParameterType.forAlphaRenaming(
sTypeVariable, tTypeVariable));
}
@@ -451,8 +451,8 @@
TypeParameter sTypeVariable = sTypeVariables[i];
TypeParameter tTypeVariable = tTypeVariables[i];
result = result.and(types.performNullabilityAwareMutualSubtypesCheck(
- substitution.substituteType(sTypeVariable.bound!),
- tTypeVariable.bound!));
+ substitution.substituteType(sTypeVariable.bound),
+ tTypeVariable.bound));
if (!result.isSubtypeWhenIgnoringNullabilities()) {
return const IsSubtypeOf.never();
}
@@ -573,7 +573,7 @@
TypeParameterType s, FunctionType t, Types types) {
// Rule 13.
return types
- .performNullabilityAwareSubtypeCheck(s.parameter.bound!, t)
+ .performNullabilityAwareSubtypeCheck(s.parameter.bound, t)
.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
}
@@ -828,9 +828,9 @@
s, t.typeArgument.withDeclaredNullability(t.nullability))
// Rule 13.
.orSubtypeCheckFor(
- s.parameter.bound!.withDeclaredNullability(
+ s.parameter.bound.withDeclaredNullability(
combineNullabilitiesForSubstitution(
- s.parameter.bound!.nullability, s.nullability)),
+ s.parameter.bound.nullability, s.nullability)),
t,
types)
// Rule 10.
diff --git a/pkg/kernel/lib/testing/type_parser_environment.dart b/pkg/kernel/lib/testing/type_parser_environment.dart
index 691610d..fcc984c 100644
--- a/pkg/kernel/lib/testing/type_parser_environment.dart
+++ b/pkg/kernel/lib/testing/type_parser_environment.dart
@@ -322,9 +322,10 @@
if (arguments.isNotEmpty) {
throw "Type variable can't have arguments (${node.name})";
}
- Nullability nullability = declaration.bound == null
- ? null
- : TypeParameterType.computeNullabilityFromBound(declaration);
+ Nullability nullability =
+ identical(declaration.bound, TypeParameter.unsetBoundSentinel)
+ ? null
+ : TypeParameterType.computeNullabilityFromBound(declaration);
TypeParameterType type = new TypeParameterType(
declaration,
interpretParsedNullability(node.parsedNullability,
diff --git a/pkg/kernel/lib/text/ast_to_text.dart b/pkg/kernel/lib/text/ast_to_text.dart
index 27edbc1..84484e7 100644
--- a/pkg/kernel/lib/text/ast_to_text.dart
+++ b/pkg/kernel/lib/text/ast_to_text.dart
@@ -2515,7 +2515,7 @@
}
writeWord(getTypeParameterName(node));
writeSpaced('extends');
- writeType(node.bound!);
+ writeType(node.bound);
if (node.defaultType != null) {
writeSpaced('=');
writeType(node.defaultType!);
diff --git a/pkg/kernel/lib/text/text_serializer.dart b/pkg/kernel/lib/text/text_serializer.dart
index 5abc570..82aaee6 100644
--- a/pkg/kernel/lib/text/text_serializer.dart
+++ b/pkg/kernel/lib/text/text_serializer.dart
@@ -1196,7 +1196,7 @@
unzipTypeParameterDefaultType);
TypeParameter zipTypeParameterBound(TypeParameter node, DartType? bound) {
- return node..bound = bound;
+ return node..bound = bound!;
}
Tuple2<TypeParameter, DartType?> unzipTypeParameterBound(TypeParameter node) {
diff --git a/pkg/kernel/lib/type_algebra.dart b/pkg/kernel/lib/type_algebra.dart
index ebf18f2..d40825c 100644
--- a/pkg/kernel/lib/type_algebra.dart
+++ b/pkg/kernel/lib/type_algebra.dart
@@ -40,7 +40,7 @@
result[parameter] = const DynamicType();
}
for (TypeParameter parameter in host.typeParameters) {
- result[parameter] = substitute(parameter.bound!, result);
+ result[parameter] = substitute(parameter.bound, result);
}
return result;
}
@@ -120,7 +120,7 @@
TypeParameter typeParameter = typeParameters[i];
TypeParameter freshTypeParameter = freshParameters[i];
- freshTypeParameter.bound = substitute(typeParameter.bound!, map);
+ freshTypeParameter.bound = substitute(typeParameter.bound, map);
freshTypeParameter.defaultType = typeParameter.defaultType != null
? substitute(typeParameter.defaultType!, map)
: null;
@@ -249,7 +249,7 @@
upper[parameter] = const DynamicType();
}
for (TypeParameter parameter in class_.typeParameters) {
- upper[parameter] = substitute(parameter.bound!, upper);
+ upper[parameter] = substitute(parameter.bound, upper);
}
return fromUpperAndLowerBounds(upper, {});
}
@@ -383,7 +383,7 @@
TypeParameter fresh = new TypeParameter(node.name);
TypeParameterType typeParameterType = substitution[node] =
new TypeParameterType.forAlphaRenaming(node, fresh);
- fresh.bound = visit(node.bound!);
+ fresh.bound = visit(node.bound);
if (node.defaultType != null) {
fresh.defaultType = visit(node.defaultType!);
}
@@ -700,7 +700,7 @@
bool handleTypeParameter(TypeParameter node) {
assert(!variables.contains(node));
- if (node.bound!.accept(this)) return true;
+ if (node.bound.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType!.accept(this);
}
@@ -759,7 +759,7 @@
bool handleTypeParameter(TypeParameter node) {
assert(variables.contains(node));
- if (node.bound!.accept(this)) return true;
+ if (node.bound.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType!.accept(this);
}
@@ -818,7 +818,7 @@
bool handleTypeParameter(TypeParameter node) {
assert(variables.contains(node));
- if (node.bound!.accept(this)) return true;
+ if (node.bound.accept(this)) return true;
if (node.defaultType == null) return false;
return node.defaultType!.accept(this);
}
@@ -1068,7 +1068,7 @@
// - The greatest closure of `S` with respect to `L` is `Function`
if (node.typeParameters.isNotEmpty) {
for (TypeParameter typeParameter in node.typeParameters) {
- if (containsTypeVariable(typeParameter.bound!, eliminationTargets,
+ if (containsTypeVariable(typeParameter.bound, eliminationTargets,
unhandledTypeHandler: unhandledTypeHandler)) {
return getFunctionReplacement(variance);
}
diff --git a/pkg/kernel/lib/verifier.dart b/pkg/kernel/lib/verifier.dart
index 9431e8e..01e2f7d 100644
--- a/pkg/kernel/lib/verifier.dart
+++ b/pkg/kernel/lib/verifier.dart
@@ -182,7 +182,7 @@
void declareTypeParameters(List<TypeParameter> parameters) {
for (int i = 0; i < parameters.length; ++i) {
TypeParameter parameter = parameters[i];
- if (parameter.bound == null) {
+ if (identical(parameter.bound, TypeParameter.unsetBoundSentinel)) {
problem(
currentParent, "Missing bound for type parameter '$parameter'.");
}
@@ -434,7 +434,7 @@
}
declareTypeParameters(node.typeParameters);
for (TypeParameter typeParameter in node.typeParameters) {
- typeParameter.bound?.accept(this);
+ typeParameter.bound.accept(this);
if (typeParameter.annotations.isNotEmpty) {
problem(
typeParameter, "Annotation on type parameter in function type.");