[analyzer] Represent `Null` as `NullTypeImpl`.

This change introduces the class `NullTypeImpl` to represent the
special type `Null`, which was previously represented as an ordinary
`InterfaceType`.

This class mirrors the CFE's `NullType` class. Adding it will
facilitate further code sharing between the analyzer and the CFE,
because it will allow code that's shared between the analyzer and CFE
to use `is` tests to recognize the type `Null`.

The new `NullTypeImpl` class always has a nullability suffix of
`NullabilitySuffix.none`, so it is impossible for the type `Null?` to
occur. This is a benign behavioral change; previously there were some
circumstances in which the type `Null?` might occur in the analyzer,
but the type `Null?` behaved the same as `Null` so there was no
user-visible effect. This behavioral change brings the analyzer's
treatment of `Null` into alignment with that of the CFE.

This is the first step in a planned patch series. In follow-up CLs, I
intend to:

- Introduce a public-facing `NullType` for use by clients.

- Change `NullTypeImpl` so that it no longer extends `InterfaceTypeImpl`.

- Add a base class that is common to the analyzer and CFE `NullType`
  representations.

Change-Id: I9cea84d8149347bffdee006d544af28c66eba429
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/396320
Commit-Queue: Paul Berry <paulberry@google.com>
Reviewed-by: Konstantin Shcheglov <scheglov@google.com>
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
diff --git a/pkg/analyzer/lib/src/dart/element/element.dart b/pkg/analyzer/lib/src/dart/element/element.dart
index 0360d91..a14e61a 100644
--- a/pkg/analyzer/lib/src/dart/element/element.dart
+++ b/pkg/analyzer/lib/src/dart/element/element.dart
@@ -5900,11 +5900,16 @@
       }
     }
 
-    var result = InterfaceTypeImpl(
-      element: this,
-      typeArguments: typeArguments,
-      nullabilitySuffix: nullabilitySuffix,
-    );
+    InterfaceTypeImpl result;
+    if (name == 'Null' && library.isDartCore) {
+      result = NullTypeImpl(element: this);
+    } else {
+      result = InterfaceTypeImpl(
+        element: this,
+        typeArguments: typeArguments,
+        nullabilitySuffix: nullabilitySuffix,
+      );
+    }
 
     if (typeArguments.isEmpty) {
       switch (nullabilitySuffix) {
@@ -10240,6 +10245,11 @@
           typeArguments: typeArguments,
         ),
       );
+    } else if (type is NullTypeImpl) {
+      return NullTypeImpl(
+          element: type.element,
+          alias: InstantiatedTypeAliasElementImpl(
+              element: this, typeArguments: typeArguments));
     } else if (type is InterfaceType) {
       return InterfaceTypeImpl(
         element: type.element,
diff --git a/pkg/analyzer/lib/src/dart/element/type.dart b/pkg/analyzer/lib/src/dart/element/type.dart
index 2e210f8..f1d5cbc 100644
--- a/pkg/analyzer/lib/src/dart/element/type.dart
+++ b/pkg/analyzer/lib/src/dart/element/type.dart
@@ -499,6 +499,9 @@
     required this.nullabilitySuffix,
     super.alias,
   }) {
+    if (element.name == 'Null' && element.library.isDartCore) {
+      throw ArgumentError('NullTypeImpl should be used for `Null`');
+    }
     if (element.augmentationTarget != null) {
       throw ArgumentError(
         'InterfaceType(s) can only be created for declarations',
@@ -516,6 +519,13 @@
     }
   }
 
+  InterfaceTypeImpl._null({required this.element, super.alias})
+      : typeArguments = const [],
+        nullabilitySuffix = NullabilitySuffix.none {
+    assert(element.name == 'Null' && element.library.isDartCore);
+    assert(this is NullTypeImpl);
+  }
+
   @override
   List<PropertyAccessorElement> get accessors {
     if (_accessors == null) {
@@ -638,11 +648,6 @@
   }
 
   @override
-  bool get isDartCoreNull {
-    return element.name == "Null" && element.library.isDartCore;
-  }
-
-  @override
   bool get isDartCoreNum {
     return element.name == "num" && element.library.isDartCore;
   }
@@ -1135,6 +1140,18 @@
   }
 }
 
+/// A concrete implementation of [DartType] representing the type `Null`, with
+/// no type parameters and no nullability suffix.
+class NullTypeImpl extends InterfaceTypeImpl {
+  NullTypeImpl({required super.element, super.alias}) : super._null();
+
+  @override
+  bool get isDartCoreNull => true;
+
+  @override
+  NullTypeImpl withNullability(NullabilitySuffix nullabilitySuffix) => this;
+}
+
 abstract class RecordTypeFieldImpl implements RecordTypeField {
   @override
   final DartType type;
diff --git a/pkg/analyzer/lib/src/dart/element/type_provider.dart b/pkg/analyzer/lib/src/dart/element/type_provider.dart
index 10d8f89..89f796b 100644
--- a/pkg/analyzer/lib/src/dart/element/type_provider.dart
+++ b/pkg/analyzer/lib/src/dart/element/type_provider.dart
@@ -608,10 +608,14 @@
       }).toList(growable: false);
     }
 
-    return InterfaceTypeImpl(
-      element: element,
-      typeArguments: typeArguments,
-      nullabilitySuffix: NullabilitySuffix.none,
-    );
+    if (element.name == 'Null' && element.library.isDartCore) {
+      return NullTypeImpl(element: element);
+    } else {
+      return InterfaceTypeImpl(
+        element: element,
+        typeArguments: typeArguments,
+        nullabilitySuffix: NullabilitySuffix.none,
+      );
+    }
   }
 }
diff --git a/pkg/analyzer/test/generated/elements_types_mixin.dart b/pkg/analyzer/test/generated/elements_types_mixin.dart
index 6457d25..aec3590 100644
--- a/pkg/analyzer/test/generated/elements_types_mixin.dart
+++ b/pkg/analyzer/test/generated/elements_types_mixin.dart
@@ -74,11 +74,6 @@
     return interfaceTypeNone(element) as InterfaceTypeImpl;
   }
 
-  InterfaceTypeImpl get nullQuestion {
-    var element = typeProvider.nullType.element;
-    return interfaceTypeQuestion(element) as InterfaceTypeImpl;
-  }
-
   InterfaceType get numNone {
     var element = typeProvider.numType.element;
     return interfaceTypeNone(element);
diff --git a/pkg/analyzer/test/src/dart/element/always_exhaustive_test.dart b/pkg/analyzer/test/src/dart/element/always_exhaustive_test.dart
index ff0ce54..5ac1068 100644
--- a/pkg/analyzer/test/src/dart/element/always_exhaustive_test.dart
+++ b/pkg/analyzer/test/src/dart/element/always_exhaustive_test.dart
@@ -36,7 +36,6 @@
 
   test_class_Null() {
     isAlwaysExhaustive(nullNone);
-    isAlwaysExhaustive(nullQuestion);
   }
 
   test_class_sealed() {
diff --git a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
index cc30ec2..ac5146f 100644
--- a/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
+++ b/pkg/analyzer/test/src/dart/element/normalize_type_test.dart
@@ -319,7 +319,7 @@
     // Analyzer: impossible, we have only one suffix
 
     // * if S is Null then Null
-    check(nullQuestion, nullNone);
+    // Analyzer: impossible; `Null?` is always represented as `Null`.
 
     // * if S is FutureOr<R> and R is nullable then S
     check(futureOrQuestion(intQuestion), futureOrNone(intQuestion));
diff --git a/pkg/analyzer/test/src/dart/element/nullable_test.dart b/pkg/analyzer/test/src/dart/element/nullable_test.dart
index ac1a68d..ebc999e 100644
--- a/pkg/analyzer/test/src/dart/element/nullable_test.dart
+++ b/pkg/analyzer/test/src/dart/element/nullable_test.dart
@@ -501,7 +501,6 @@
 
   test_null() {
     isNotStrictlyNonNullable(nullNone);
-    isNotStrictlyNonNullable(nullQuestion);
   }
 
   test_typeParameter_boundNone() {
diff --git a/pkg/analyzer/test/src/dart/element/string_types.dart b/pkg/analyzer/test/src/dart/element/string_types.dart
index bdd3738..9645e00 100644
--- a/pkg/analyzer/test/src/dart/element/string_types.dart
+++ b/pkg/analyzer/test/src/dart/element/string_types.dart
@@ -28,7 +28,7 @@
     _defineType('Never', neverNone);
     _defineType('Never?', neverQuestion);
 
-    _defineType('Null?', nullQuestion);
+    _defineType('Null', nullNone);
 
     _defineType('Object', objectNone);
     _defineType('Object?', objectQuestion);
diff --git a/pkg/analyzer/test/src/dart/element/subtype_test.dart b/pkg/analyzer/test/src/dart/element/subtype_test.dart
index 6008ff1..c50ef18 100644
--- a/pkg/analyzer/test/src/dart/element/subtype_test.dart
+++ b/pkg/analyzer/test/src/dart/element/subtype_test.dart
@@ -1989,14 +1989,14 @@
     );
 
     isSubtype(
-      nullQuestion,
+      nullNone,
       functionTypeQuestion(
         parameters: [
           requiredParameter(type: intNone),
         ],
         returnType: numNone,
       ),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'num Function(int)?',
     );
   }
@@ -2205,18 +2205,18 @@
 
   test_futureOr_13() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       futureOrNone(intNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'FutureOr<int>',
     );
   }
 
   test_futureOr_14() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       futureQuestion(intNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'Future<int>?',
     );
   }
@@ -2841,8 +2841,8 @@
 
     isNotSubtype2('int Function(int)', 'num Function(num)');
 
-    isNotSubtype2('Null?', 'num Function(int)');
-    isSubtype2('Null?', 'num Function(int)?');
+    isNotSubtype2('Null', 'num Function(int)');
+    isSubtype2('Null', 'num Function(int)?');
 
     isSubtype2('Never', 'num Function(int)');
     isSubtype2('Never', 'num Function(int)?');
@@ -2898,8 +2898,8 @@
     isSubtype2('FutureOr<int>', 'FutureOr<int>');
     isSubtype2('FutureOr<int>', 'FutureOr<num>');
     isSubtype2('FutureOr<int>', 'Object');
-    isSubtype2('Null?', 'FutureOr<num?>');
-    isSubtype2('Null?', 'FutureOr<num>?');
+    isSubtype2('Null', 'FutureOr<num?>');
+    isSubtype2('Null', 'FutureOr<num>?');
     isSubtype2('num?', 'FutureOr<num?>');
     isSubtype2('num?', 'FutureOr<num>?');
     isSubtype2('Future<num>', 'FutureOr<num?>');
@@ -3380,8 +3380,8 @@
     isSubtype2('List<int>', 'List<Comparable<num>>');
     isSubtype2('List<int>', 'List<Comparable<Comparable<num>>>');
     isSubtype2('List<int>', 'Object');
-    isNotSubtype2('Null?', 'List<int>');
-    isSubtype2('Null?', 'List<int>?');
+    isNotSubtype2('Null', 'List<int>');
+    isSubtype2('Null', 'List<int>?');
     isSubtype2('Never', 'List<int>');
     isSubtype2('Never', 'List<int>?');
 
@@ -3408,7 +3408,7 @@
     isSubtype2('int', 'Comparable<Object>');
     isSubtype2('double', 'num');
     isSubtype2('num', 'Object');
-    isSubtype2('Null?', 'num?');
+    isSubtype2('Null', 'num?');
     isSubtype2('Never', 'num');
     isSubtype2('Never', 'num?');
 
@@ -3417,7 +3417,7 @@
     isNotSubtype2('int', 'Iterable<int>');
     isNotSubtype2('Comparable<int>', 'Iterable<int>');
     isNotSubtype2('num?', 'Object');
-    isNotSubtype2('Null?', 'num');
+    isNotSubtype2('Null', 'num');
     isNotSubtype2('num', 'Never');
   }
 
@@ -3428,7 +3428,7 @@
     isSubtype2('Object', 'Object?');
 
     isNotSubtype2('Object', 'Never');
-    isNotSubtype2('Object', 'Null?');
+    isNotSubtype2('Object', 'Null');
     isNotSubtype2('dynamic', 'Object');
     isNotSubtype2('void', 'Object');
     isNotSubtype2('Object?', 'Object');
@@ -3451,13 +3451,13 @@
   }
 
   test_multi_topAndBottom() {
-    isSubtype2('Null?', 'Null?');
-    isSubtype2('Never', 'Null?');
+    isSubtype2('Null', 'Null');
+    isSubtype2('Never', 'Null');
     isSubtype2('Never', 'Never');
-    isNotSubtype2('Null?', 'Never');
+    isNotSubtype2('Null', 'Never');
 
-    isSubtype2('Null?', 'Never?');
-    isSubtype2('Never?', 'Null?');
+    isSubtype2('Null', 'Never?');
+    isSubtype2('Never?', 'Null');
     isSubtype2('Never', 'Never?');
     isNotSubtype2('Never?', 'Never');
 
@@ -3474,16 +3474,16 @@
     isSubtype2('Never', 'Object?');
     isSubtype2('Never', 'dynamic');
     isSubtype2('Never', 'void');
-    isSubtype2('Null?', 'Object?');
-    isSubtype2('Null?', 'dynamic');
-    isSubtype2('Null?', 'void');
+    isSubtype2('Null', 'Object?');
+    isSubtype2('Null', 'dynamic');
+    isSubtype2('Null', 'void');
 
     isNotSubtype2('Object?', 'Never');
-    isNotSubtype2('Object?', 'Null?');
+    isNotSubtype2('Object?', 'Null');
     isNotSubtype2('dynamic', 'Never');
-    isNotSubtype2('dynamic', 'Null?');
+    isNotSubtype2('dynamic', 'Null');
     isNotSubtype2('void', 'Never');
-    isNotSubtype2('void', 'Null?');
+    isNotSubtype2('void', 'Null');
   }
 
   test_multi_typeParameter_promotion() {
@@ -3746,68 +3746,68 @@
   }
 
   test_never_29() {
-    isSubtype(neverNone, nullQuestion, strT0: 'Never', strT1: 'Null?');
+    isSubtype(neverNone, nullNone, strT0: 'Never', strT1: 'Null');
   }
 
   test_null_01() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       neverNone,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'Never',
     );
   }
 
   test_null_02() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       objectNone,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'Object',
     );
   }
 
   test_null_03() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       voidNone,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'void',
     );
   }
 
   test_null_04() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       dynamicType,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'dynamic',
     );
   }
 
   test_null_05() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       doubleNone,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'double',
     );
   }
 
   test_null_06() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       doubleQuestion,
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'double?',
     );
   }
 
   test_null_07() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       comparableNone(objectNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'Comparable<Object>',
     );
   }
@@ -3816,69 +3816,69 @@
     var T = typeParameter('T', bound: objectNone);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeNone(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T, T extends Object',
     );
   }
 
   test_null_09() {
     isSubtype(
-      nullQuestion,
-      nullQuestion,
-      strT0: 'Null?',
-      strT1: 'Null?',
+      nullNone,
+      nullNone,
+      strT0: 'Null',
+      strT1: 'Null',
     );
   }
 
   test_null_10() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       listNone(intNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'List<int>',
     );
   }
 
   test_null_13() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       functionTypeNone(
         returnType: numNone,
         parameters: [
           requiredParameter(type: intNone),
         ],
       ),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'num Function(int)',
     );
   }
 
   test_null_14() {
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       functionTypeNone(
         returnType: numNone,
         parameters: [
           requiredParameter(type: intNone),
         ],
       ),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'num Function(int)',
     );
   }
 
   test_null_15() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       functionTypeQuestion(
         returnType: numNone,
         parameters: [
           requiredParameter(type: intNone),
         ],
       ),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'num Function(int)?',
     );
   }
@@ -3887,9 +3887,9 @@
     var T = typeParameter('T', bound: objectNone);
 
     isSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeQuestion(T, numNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: '(T & num)?, T extends Object',
     );
   }
@@ -3898,9 +3898,9 @@
     var T = typeParameter('T', bound: objectQuestion);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeNone(T, numNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T & num, T extends Object?',
     );
   }
@@ -3909,9 +3909,9 @@
     var T = typeParameter('T', bound: objectQuestion);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeNone(T, numQuestion),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T & num?, T extends Object?',
     );
   }
@@ -3920,9 +3920,9 @@
     var T = typeParameter('T', bound: objectNone);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeNone(T, numNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T & num, T extends Object',
     );
   }
@@ -3932,9 +3932,9 @@
     var S = typeParameter('S', bound: typeParameterTypeNone(T));
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeNone(T, typeParameterTypeNone(S)),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T & S, T extends Object?',
     );
   }
@@ -3943,9 +3943,9 @@
     var T = typeParameter('T', bound: objectNone);
 
     isSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeQuestion(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T?, T extends Object',
     );
   }
@@ -3954,9 +3954,9 @@
     var T = typeParameter('T', bound: objectQuestion);
 
     isSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeQuestion(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T?, T extends Object?',
     );
   }
@@ -3965,9 +3965,9 @@
     var T = typeParameter('T', bound: objectNone);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeNone(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T, T extends Object',
     );
   }
@@ -3976,32 +3976,32 @@
     var T = typeParameter('T', bound: objectQuestion);
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeNone(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T, T extends Object?',
     );
   }
 
   test_null_25() {
-    var T = typeParameter('T', bound: nullQuestion);
+    var T = typeParameter('T', bound: nullNone);
 
     isSubtype(
       typeParameterTypeNone(T),
-      nullQuestion,
-      strT0: 'T, T extends Null?',
-      strT1: 'Null?',
+      nullNone,
+      strT0: 'T, T extends Null',
+      strT1: 'Null',
     );
   }
 
   test_null_26() {
-    var T = typeParameter('T', bound: nullQuestion);
+    var T = typeParameter('T', bound: nullNone);
 
     isSubtype(
       typeParameterTypeQuestion(T),
-      nullQuestion,
-      strT0: 'T?, T extends Null?',
-      strT1: 'Null?',
+      nullNone,
+      strT0: 'T?, T extends Null',
+      strT1: 'Null',
     );
   }
 
@@ -4010,9 +4010,9 @@
 
     isNotSubtype(
       typeParameterTypeNone(T),
-      nullQuestion,
+      nullNone,
       strT0: 'T, T extends Object',
-      strT1: 'Null?',
+      strT1: 'Null',
     );
   }
 
@@ -4021,23 +4021,23 @@
 
     isNotSubtype(
       typeParameterTypeNone(T),
-      nullQuestion,
+      nullNone,
       strT0: 'T, T extends Object?',
-      strT1: 'Null?',
+      strT1: 'Null',
     );
   }
 
   test_null_29() {
     isSubtype(
-      nullQuestion,
+      nullNone,
       comparableQuestion(objectNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'Comparable<Object>?',
     );
   }
 
   test_null_30() {
-    isNotSubtype(nullQuestion, objectNone, strT0: 'Null?', strT1: 'Object');
+    isNotSubtype(nullNone, objectNone, strT0: 'Null', strT1: 'Object');
   }
 
   test_nullabilitySuffix_01() {
@@ -4840,9 +4840,9 @@
     var T = typeParameter('T');
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       promotedTypeParameterTypeNone(T, numNone),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T & num',
     );
   }
@@ -5194,9 +5194,9 @@
     var T = typeParameter('T');
 
     isNotSubtype(
-      nullQuestion,
+      nullNone,
       typeParameterTypeNone(T),
-      strT0: 'Null?',
+      strT0: 'Null',
       strT1: 'T',
     );
   }
@@ -5410,7 +5410,6 @@
     var unrelated = <DartType>[
       doubleNone,
       nullNone,
-      nullQuestion,
       neverQuestion,
     ];
 
@@ -5431,7 +5430,6 @@
     var subtypes = <DartType>[
       intNone,
       nullNone,
-      nullQuestion,
       neverNone,
       neverQuestion,
     ];
@@ -5459,7 +5457,6 @@
   test_null() {
     var equivalents = <DartType>[
       nullNone,
-      nullQuestion,
       neverQuestion,
     ];
 
diff --git a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
index dcd7586..7b62180 100644
--- a/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
+++ b/pkg/analyzer/test/src/dart/element/upper_lower_bound_test.dart
@@ -152,29 +152,20 @@
     isMoreBottom(neverNone, neverQuestion);
 
     isMoreBottom(neverNone, nullNone);
-    isMoreBottom(neverNone, nullQuestion);
 
     // MOREBOTTOM(T, Never) = false
     isNotMoreBottom(neverQuestion, neverNone);
 
     isNotMoreBottom(nullNone, neverNone);
-    isNotMoreBottom(nullQuestion, neverNone);
 
     // MOREBOTTOM(Null, T) = true
     isMoreBottom(nullNone, neverQuestion);
 
     isMoreBottom(nullNone, nullNone);
-    isMoreBottom(nullNone, nullQuestion);
 
     // MOREBOTTOM(T, Null) = false
     isNotMoreBottom(neverQuestion, nullNone);
 
-    isNotMoreBottom(nullQuestion, nullNone);
-
-    // MOREBOTTOM(T?, S?) = MOREBOTTOM(T, S)
-    isMoreBottom(neverQuestion, nullQuestion);
-    isNotMoreBottom(nullQuestion, neverQuestion);
-
     // MOREBOTTOM(X&T, Y&S) = MOREBOTTOM(T, S)
     isMoreBottom(
       promotedTypeParameterTypeNone(
@@ -309,7 +300,6 @@
     isNull(nullNone);
 
     // NULL(T?) is true iff NULL(T) or BOTTOM(T)
-    isNull(nullQuestion);
     isNull(neverQuestion);
     isNull(
       typeParameterTypeQuestion(
@@ -329,10 +319,8 @@
     isNotNull(intQuestion);
 
     isNotNull(futureOrNone(nullNone));
-    isNotNull(futureOrNone(nullQuestion));
 
     isNotNull(futureOrQuestion(nullNone));
-    isNotNull(futureOrQuestion(nullQuestion));
   }
 
   test_isObject() {
@@ -979,10 +967,8 @@
     }
 
     checkNull(futureOrNone(nullNone));
-    checkNull(futureOrNone(nullQuestion));
 
     checkNull(futureOrQuestion(nullNone));
-    checkNull(futureOrQuestion(nullQuestion));
 
     checkNever(objectNone);
 
@@ -1007,8 +993,7 @@
       _checkGreatestLowerBound(T1, T2, T1);
     }
 
-    check(nullNone, nullQuestion);
-    check(nullQuestion, nullQuestion);
+    check(nullNone, nullNone);
   }
 
   test_object_any() {
@@ -2734,9 +2719,6 @@
     check(nullNone, intNone, intQuestion);
     check(nullNone, intQuestion, intQuestion);
 
-    check(nullQuestion, intNone, intQuestion);
-    check(nullQuestion, intQuestion, intQuestion);
-
     check(nullNone, listNone(intNone), listQuestion(intNone));
     check(nullNone, listQuestion(intNone), listQuestion(intNone));
 
@@ -2768,8 +2750,7 @@
       _checkLeastUpperBound(T1, T2, T2);
     }
 
-    check(nullNone, nullQuestion);
-    check(nullQuestion, nullQuestion);
+    check(nullNone, nullNone);
   }
 
   test_object_any() {