[cfe] Handle required parameters in subtype check

+ use legacy erasure on weak mode const object checking
+ changes Null to subtype of Never when ignoring nullabilities

Closes #43606
Closes #43624

Change-Id: Ief695829c550562ec1bfd0c1145cc33c584a4b8a
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/165805
Commit-Queue: Johnni Winther <johnniwinther@google.com>
Reviewed-by: Dmitry Stefantsov <dmitryas@google.com>
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 d799e39..8618dbe 100644
--- a/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
+++ b/pkg/front_end/lib/src/fasta/kernel/constant_evaluator.dart
@@ -2549,6 +2549,9 @@
 
   bool isSubtype(Constant constant, DartType type, SubtypeCheckMode mode) {
     DartType constantType = constant.getType(_staticTypeContext);
+    if (mode == SubtypeCheckMode.ignoringNullabilities) {
+      constantType = rawLegacyErasure(coreTypes, constantType) ?? constantType;
+    }
     bool result = typeEnvironment.isSubtypeOf(constantType, type, mode);
     if (targetingJavaScript && !result) {
       if (constantType is InterfaceType &&
diff --git a/pkg/front_end/test/fasta/types/shared_type_tests.dart b/pkg/front_end/test/fasta/types/shared_type_tests.dart
index 37a43e8..fa1d750 100644
--- a/pkg/front_end/test/fasta/types/shared_type_tests.dart
+++ b/pkg/front_end/test/fasta/types/shared_type_tests.dart
@@ -696,7 +696,7 @@
     // Tests for bottom and top types.
     isSubtype('Null', 'Null');
     isNotSubtype('Null', 'bottom');
-    isNotSubtype('Null', 'Never');
+    isObliviousSubtype('Null', 'Never');
     isSubtype('bottom', 'Null');
     isSubtype('bottom', 'bottom');
     isSubtype('bottom', 'Never');
@@ -889,7 +889,7 @@
     isSubtype('Never', 'Id<Object>');
     isSubtype('Never', 'Id<Never>');
     isSubtype('Id<Never>', 'Never');
-    isNotSubtype('Null', 'Id<Never>');
+    isObliviousSubtype('Null', 'Id<Never>');
     isSubtype('Id<Never>', 'Null');
     isNotSubtype('Id<Object>', 'Never');
     isSubtype('Id<int>', 'num');
diff --git a/pkg/front_end/test/spell_checking_list_code.txt b/pkg/front_end/test/spell_checking_list_code.txt
index 17ed18c..16c406d 100644
--- a/pkg/front_end/test/spell_checking_list_code.txt
+++ b/pkg/front_end/test/spell_checking_list_code.txt
@@ -851,6 +851,7 @@
 r'\u
 r'\v
 r0i
+r0j
 r1i
 r2i
 ra
@@ -1309,6 +1310,7 @@
 xdfff
 xef
 xi
+xj
 xk
 xm
 xn
@@ -1328,6 +1330,7 @@
 yaml
 yb
 yet
+yi
 yielding
 yields
 yn
diff --git a/pkg/front_end/test/spell_checking_list_tests.txt b/pkg/front_end/test/spell_checking_list_tests.txt
index eaf2af5..bef5e7f 100644
--- a/pkg/front_end/test/spell_checking_list_tests.txt
+++ b/pkg/front_end/test/spell_checking_list_tests.txt
@@ -216,6 +216,7 @@
 eoo
 epoch
 erase
+erased
 err
 esc
 everytime
@@ -440,9 +441,12 @@
 nonexisting
 noo
 numerator
+ob
+obool
 observable
 oh
 okay
+ol
 onull
 ooo
 operate
@@ -453,6 +457,7 @@
 out2
 outbound
 overlay
+ox
 pack
 paging
 paint
@@ -679,3 +684,4 @@
 y's
 year
 yxxx
+yy
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart b/pkg/front_end/testcases/nnbd/const_is.dart
new file mode 100644
index 0000000..ccafc28
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart
@@ -0,0 +1,181 @@
+// 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.
+
+// Tests derived from co19/Language/Types/Function_Types/subtype_named_args_t04
+// and language/nnbd/subtyping/function_type_required_params_test
+
+bool inStrongMode = <int?>[] is! List<int>;
+
+int f({required int i}) {
+  return i + 1;
+}
+
+int g({int i = 1}) {
+  return i + 1;
+}
+
+typedef int fType({required int i});
+typedef int gType({int i});
+typedef int bigType(
+    {required int i1,
+    required int i2,
+    required int i3,
+    required int i4,
+    required int i5,
+    required int i6,
+    required int i7,
+    required int i8,
+    required int i9,
+    required int i10,
+    required int i11,
+    required int i12,
+    required int i13,
+    required int i14,
+    required int i15,
+    required int i16,
+    required int i17,
+    required int i18,
+    required int i19,
+    required int i20,
+    required int i21,
+    required int i22,
+    required int i23,
+    required int i24,
+    required int i25,
+    required int i26,
+    required int i27,
+    required int i28,
+    required int i29,
+    required int i30,
+    required int i31,
+    required int i32,
+    required int i33,
+    required int i34,
+    required int i35,
+    required int i36,
+    required int i37,
+    required int i38,
+    required int i39,
+    required int i40,
+    required int i41,
+    required int i42,
+    required int i43,
+    required int i44,
+    required int i45,
+    required int i46,
+    required int i47,
+    required int i48,
+    required int i49,
+    required int i50,
+    required int i51,
+    required int i52,
+    required int i53,
+    required int i54,
+    required int i55,
+    required int i56,
+    required int i57,
+    required int i58,
+    required int i59,
+    required int i60,
+    required int i61,
+    required int i62,
+    required int i63,
+    required int i64,
+    required int i65,
+    required int i66,
+    required int i67,
+    required int i68,
+    required int i69,
+    required int i70});
+
+class A {}
+
+class A1 {}
+
+class A2 {}
+
+class B implements A, A1, A2 {}
+
+class C implements B {}
+
+class D implements C {}
+
+typedef B func(Object o);
+typedef B t1(int i, B b, Map<int, num> m, var x,
+    {required var ox,
+    required B ob,
+    required List<num> ol,
+    required bool obool});
+
+B f1(int i, B b, Map<int, num> m, var x,
+        {required extraParam,
+        required bool obool,
+        required var ox,
+        required D ob,
+        required List<num>? ol}) =>
+    new B();
+D f2(int i, D b, Map<int, int> m, func x,
+        {required func ox,
+        required D ob,
+        required List<int> ol,
+        required bool obool}) =>
+    new D();
+C f3(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required extraParam,
+        required A2 ob,
+        required List ol,
+        required Object obool}) =>
+    new C();
+C f4(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required A2 ob,
+        required List ol,
+        required bool obool,
+        required A xx,
+        required B yy}) =>
+    new C();
+C f5(int i, A b, Map<Object, Object> m, var x,
+        {required ox, required B ob, required List ol, required obool}) =>
+    new C();
+
+const f_is_fType = f is fType;
+const f_is_gType = f is gType;
+const g_is_fType = g is fType;
+const g_is_gType = g is gType;
+const f_is_bigType = f is bigType;
+
+const f1_is_t1 = f1 is t1;
+const f2_is_t1 = f2 is t1;
+const f3_is_t1 = f3 is t1;
+const f4_is_t1 = f4 is t1;
+const f5_is_t1 = f5 is t1;
+
+main() {
+  expect(true, f_is_fType);
+  expect(f is fType, f_is_fType);
+  expect(!inStrongMode, f_is_gType);
+  expect(f is gType, f_is_gType);
+  expect(true, g_is_fType);
+  expect(g is fType, g_is_fType);
+  expect(true, g_is_gType);
+  expect(g is gType, g_is_gType);
+  expect(false, f_is_bigType);
+  expect(f is bigType, f_is_bigType);
+
+  expect(false, f1_is_t1);
+  expect(f1 is t1, f1_is_t1);
+  expect(false, f2_is_t1);
+  expect(f2 is t1, f2_is_t1);
+  expect(!inStrongMode, f3_is_t1);
+  expect(f3 is t1, f3_is_t1);
+  expect(!inStrongMode, f4_is_t1);
+  expect(f4 is t1, f4_is_t1);
+  expect(true, f5_is_t1);
+  expect(f5 is t1, f5_is_t1);
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw "Expected $expected, actual $actual";
+}
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.outline.expect b/pkg/front_end/testcases/nnbd/const_is.dart.outline.expect
new file mode 100644
index 0000000..46bacdc
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.outline.expect
@@ -0,0 +1,76 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef fType = ({required i: core::int}) → core::int;
+typedef gType = ({i: core::int}) → core::int;
+typedef bigType = ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+typedef func = (core::Object) → self::B;
+typedef t1 = (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    ;
+}
+class A2 extends core::Object {
+  synthetic constructor •() → self::A2
+    ;
+}
+class B extends core::Object implements self::A, self::A1, self::A2 {
+  synthetic constructor •() → self::B
+    ;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    ;
+}
+class D extends core::Object implements self::C {
+  synthetic constructor •() → self::D
+    ;
+}
+static field core::bool inStrongMode;
+static const field core::bool f_is_fType = self::f is{ForNonNullableByDefault} ({required i: core::int}) → core::int;
+static const field core::bool f_is_gType = self::f is{ForNonNullableByDefault} ({i: core::int}) → core::int;
+static const field core::bool g_is_fType = self::g is{ForNonNullableByDefault} ({required i: core::int}) → core::int;
+static const field core::bool g_is_gType = self::g is{ForNonNullableByDefault} ({i: core::int}) → core::int;
+static const field core::bool f_is_bigType = self::f is{ForNonNullableByDefault} ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+static const field core::bool f1_is_t1 = self::f1 is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+static const field core::bool f2_is_t1 = self::f2 is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+static const field core::bool f3_is_t1 = self::f3 is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+static const field core::bool f4_is_t1 = self::f4 is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+static const field core::bool f5_is_t1 = self::f5 is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+static method f({required core::int i}) → core::int
+  ;
+static method g({core::int i}) → core::int
+  ;
+static method f1(core::int i, self::B b, core::Map<core::int, core::num> m, dynamic x, {required dynamic extraParam, required core::bool obool, required dynamic ox, required self::D ob, required core::List<core::num>? ol}) → self::B
+  ;
+static method f2(core::int i, self::D b, core::Map<core::int, core::int> m, (core::Object) → self::B x, {required (core::Object) → self::B ox, required self::D ob, required core::List<core::int> ol, required core::bool obool}) → self::D
+  ;
+static method f3(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox, required dynamic extraParam, required self::A2 ob, required core::List<dynamic> ol, required core::Object obool}) → self::C
+  ;
+static method f4(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox, required self::A2 ob, required core::List<dynamic> ol, required core::bool obool, required self::A xx, required self::B yy}) → self::C
+  ;
+static method f5(core::int i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox, required self::B ob, required core::List<dynamic> ol, required dynamic obool}) → self::C
+  ;
+static method main() → dynamic
+  ;
+static method expect(dynamic expected, dynamic actual) → dynamic
+  ;
+
+
+Extra constant evaluation status:
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:143:22 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:144:22 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:145:22 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:146:22 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:147:24 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:149:21 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:150:21 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:151:21 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:152:21 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:153:21 -> BoolConstant(true)
+Extra constant evaluation: evaluated: 10, effectively constant: 10
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.strong.expect b/pkg/front_end/testcases/nnbd/const_is.dart.strong.expect
new file mode 100644
index 0000000..ecdde5d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.strong.expect
@@ -0,0 +1,106 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef fType = ({required i: core::int}) → core::int;
+typedef gType = ({i: core::int}) → core::int;
+typedef bigType = ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+typedef func = (core::Object) → self::B;
+typedef t1 = (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+}
+class A2 extends core::Object {
+  synthetic constructor •() → self::A2
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A, self::A1, self::A2 {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+static field core::bool inStrongMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static const field core::bool f_is_fType = #C1;
+static const field core::bool f_is_gType = #C2;
+static const field core::bool g_is_fType = #C1;
+static const field core::bool g_is_gType = #C1;
+static const field core::bool f_is_bigType = #C2;
+static const field core::bool f1_is_t1 = #C2;
+static const field core::bool f2_is_t1 = #C2;
+static const field core::bool f3_is_t1 = #C2;
+static const field core::bool f4_is_t1 = #C2;
+static const field core::bool f5_is_t1 = #C1;
+static method f({required core::int i = #C3}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method g({core::int i = #C4}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method f1(core::int i, self::B b, core::Map<core::int, core::num> m, dynamic x, {required dynamic extraParam = #C3, required core::bool obool = #C3, required dynamic ox = #C3, required self::D ob = #C3, required core::List<core::num>? ol = #C3}) → self::B
+  return new self::B::•();
+static method f2(core::int i, self::D b, core::Map<core::int, core::int> m, (core::Object) → self::B x, {required (core::Object) → self::B ox = #C3, required self::D ob = #C3, required core::List<core::int> ol = #C3, required core::bool obool = #C3}) → self::D
+  return new self::D::•();
+static method f3(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required dynamic extraParam = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::Object obool = #C3}) → self::C
+  return new self::C::•();
+static method f4(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::bool obool = #C3, required self::A xx = #C3, required self::B yy = #C3}) → self::C
+  return new self::C::•();
+static method f5(core::int i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::B ob = #C3, required core::List<dynamic> ol = #C3, required dynamic obool = #C3}) → self::C
+  return new self::C::•();
+static method main() → dynamic {
+  self::expect(true, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C2);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(false, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int, #C2);
+  self::expect(false, #C2);
+  self::expect((#C7) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(false, #C2);
+  self::expect((#C8) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C9) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C10) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(true, #C1);
+  self::expect((#C11) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+  #C3 = null
+  #C4 = 1
+  #C5 = tearoff self::f
+  #C6 = tearoff self::g
+  #C7 = tearoff self::f1
+  #C8 = tearoff self::f2
+  #C9 = tearoff self::f3
+  #C10 = tearoff self::f4
+  #C11 = tearoff self::f5
+}
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.strong.transformed.expect b/pkg/front_end/testcases/nnbd/const_is.dart.strong.transformed.expect
new file mode 100644
index 0000000..1ba909d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.strong.transformed.expect
@@ -0,0 +1,119 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef fType = ({required i: core::int}) → core::int;
+typedef gType = ({i: core::int}) → core::int;
+typedef bigType = ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+typedef func = (core::Object) → self::B;
+typedef t1 = (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+}
+class A2 extends core::Object {
+  synthetic constructor •() → self::A2
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A, self::A1, self::A2 {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+static field core::bool inStrongMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static const field core::bool f_is_fType = #C1;
+static const field core::bool f_is_gType = #C2;
+static const field core::bool g_is_fType = #C1;
+static const field core::bool g_is_gType = #C1;
+static const field core::bool f_is_bigType = #C2;
+static const field core::bool f1_is_t1 = #C2;
+static const field core::bool f2_is_t1 = #C2;
+static const field core::bool f3_is_t1 = #C2;
+static const field core::bool f4_is_t1 = #C2;
+static const field core::bool f5_is_t1 = #C1;
+static method f({required core::int i = #C3}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method g({core::int i = #C4}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method f1(core::int i, self::B b, core::Map<core::int, core::num> m, dynamic x, {required dynamic extraParam = #C3, required core::bool obool = #C3, required dynamic ox = #C3, required self::D ob = #C3, required core::List<core::num>? ol = #C3}) → self::B
+  return new self::B::•();
+static method f2(core::int i, self::D b, core::Map<core::int, core::int> m, (core::Object) → self::B x, {required (core::Object) → self::B ox = #C3, required self::D ob = #C3, required core::List<core::int> ol = #C3, required core::bool obool = #C3}) → self::D
+  return new self::D::•();
+static method f3(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required dynamic extraParam = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::Object obool = #C3}) → self::C
+  return new self::C::•();
+static method f4(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::bool obool = #C3, required self::A xx = #C3, required self::B yy = #C3}) → self::C
+  return new self::C::•();
+static method f5(core::int i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::B ob = #C3, required core::List<dynamic> ol = #C3, required dynamic obool = #C3}) → self::C
+  return new self::C::•();
+static method main() → dynamic {
+  self::expect(true, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C2);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(false, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int, #C2);
+  self::expect(false, #C2);
+  self::expect((#C7) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(false, #C2);
+  self::expect((#C8) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C9) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C2);
+  self::expect((#C10) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(true, #C1);
+  self::expect((#C11) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+  #C3 = null
+  #C4 = 1
+  #C5 = tearoff self::f
+  #C6 = tearoff self::g
+  #C7 = tearoff self::f1
+  #C8 = tearoff self::f2
+  #C9 = tearoff self::f3
+  #C10 = tearoff self::f4
+  #C11 = tearoff self::f5
+}
+
+Extra constant evaluation status:
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:157:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:159:12 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:161:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:163:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:165:12 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:168:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:170:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:172:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:174:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:176:13 -> BoolConstant(true)
+Extra constant evaluation: evaluated: 56, effectively constant: 10
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline.expect
new file mode 100644
index 0000000..48d1d0a
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline.expect
@@ -0,0 +1,138 @@
+bool inStrongMode = <int?>[] is! List<int>;
+int f({required int i}) {}
+int g({int i = 1}) {}
+typedef int fType({required int i});
+typedef int gType({int i});
+typedef int bigType(
+    {required int i1,
+    required int i2,
+    required int i3,
+    required int i4,
+    required int i5,
+    required int i6,
+    required int i7,
+    required int i8,
+    required int i9,
+    required int i10,
+    required int i11,
+    required int i12,
+    required int i13,
+    required int i14,
+    required int i15,
+    required int i16,
+    required int i17,
+    required int i18,
+    required int i19,
+    required int i20,
+    required int i21,
+    required int i22,
+    required int i23,
+    required int i24,
+    required int i25,
+    required int i26,
+    required int i27,
+    required int i28,
+    required int i29,
+    required int i30,
+    required int i31,
+    required int i32,
+    required int i33,
+    required int i34,
+    required int i35,
+    required int i36,
+    required int i37,
+    required int i38,
+    required int i39,
+    required int i40,
+    required int i41,
+    required int i42,
+    required int i43,
+    required int i44,
+    required int i45,
+    required int i46,
+    required int i47,
+    required int i48,
+    required int i49,
+    required int i50,
+    required int i51,
+    required int i52,
+    required int i53,
+    required int i54,
+    required int i55,
+    required int i56,
+    required int i57,
+    required int i58,
+    required int i59,
+    required int i60,
+    required int i61,
+    required int i62,
+    required int i63,
+    required int i64,
+    required int i65,
+    required int i66,
+    required int i67,
+    required int i68,
+    required int i69,
+    required int i70});
+
+class A {}
+
+class A1 {}
+
+class A2 {}
+
+class B implements A, A1, A2 {}
+
+class C implements B {}
+
+class D implements C {}
+
+typedef B func(Object o);
+typedef B t1(int i, B b, Map<int, num> m, var x,
+    {required var ox,
+    required B ob,
+    required List<num> ol,
+    required bool obool});
+B f1(int i, B b, Map<int, num> m, var x,
+        {required extraParam,
+        required bool obool,
+        required var ox,
+        required D ob,
+        required List<num>? ol}) =>
+    new B();
+D f2(int i, D b, Map<int, int> m, func x,
+        {required func ox,
+        required D ob,
+        required List<int> ol,
+        required bool obool}) =>
+    new D();
+C f3(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required extraParam,
+        required A2 ob,
+        required List ol,
+        required Object obool}) =>
+    new C();
+C f4(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required A2 ob,
+        required List ol,
+        required bool obool,
+        required A xx,
+        required B yy}) =>
+    new C();
+C f5(int i, A b, Map<Object, Object> m, var x,
+        {required ox, required B ob, required List ol, required obool}) =>
+    new C();
+const f_is_fType = f is fType;
+const f_is_gType = f is gType;
+const g_is_fType = g is fType;
+const g_is_gType = g is gType;
+const f_is_bigType = f is bigType;
+const f1_is_t1 = f1 is t1;
+const f2_is_t1 = f2 is t1;
+const f3_is_t1 = f3 is t1;
+const f4_is_t1 = f4 is t1;
+const f5_is_t1 = f5 is t1;
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..5e166ea
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,138 @@
+B f1(int i, B b, Map<int, num> m, var x,
+        {required extraParam,
+        required bool obool,
+        required var ox,
+        required D ob,
+        required List<num>? ol}) =>
+    new B();
+C f3(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required extraParam,
+        required A2 ob,
+        required List ol,
+        required Object obool}) =>
+    new C();
+C f4(num i, A b, Map<Object, Object> m, var x,
+        {required var ox,
+        required A2 ob,
+        required List ol,
+        required bool obool,
+        required A xx,
+        required B yy}) =>
+    new C();
+C f5(int i, A b, Map<Object, Object> m, var x,
+        {required ox, required B ob, required List ol, required obool}) =>
+    new C();
+D f2(int i, D b, Map<int, int> m, func x,
+        {required func ox,
+        required D ob,
+        required List<int> ol,
+        required bool obool}) =>
+    new D();
+bool inStrongMode = <int?>[] is! List<int>;
+
+class A {}
+
+class A1 {}
+
+class A2 {}
+
+class B implements A, A1, A2 {}
+
+class C implements B {}
+
+class D implements C {}
+
+const f1_is_t1 = f1 is t1;
+const f2_is_t1 = f2 is t1;
+const f3_is_t1 = f3 is t1;
+const f4_is_t1 = f4 is t1;
+const f5_is_t1 = f5 is t1;
+const f_is_bigType = f is bigType;
+const f_is_fType = f is fType;
+const f_is_gType = f is gType;
+const g_is_fType = g is fType;
+const g_is_gType = g is gType;
+expect(expected, actual) {}
+int f({required int i}) {}
+int g({int i = 1}) {}
+main() {}
+typedef B func(Object o);
+typedef B t1(int i, B b, Map<int, num> m, var x,
+    {required var ox,
+    required B ob,
+    required List<num> ol,
+    required bool obool});
+typedef int bigType(
+    {required int i1,
+    required int i2,
+    required int i3,
+    required int i4,
+    required int i5,
+    required int i6,
+    required int i7,
+    required int i8,
+    required int i9,
+    required int i10,
+    required int i11,
+    required int i12,
+    required int i13,
+    required int i14,
+    required int i15,
+    required int i16,
+    required int i17,
+    required int i18,
+    required int i19,
+    required int i20,
+    required int i21,
+    required int i22,
+    required int i23,
+    required int i24,
+    required int i25,
+    required int i26,
+    required int i27,
+    required int i28,
+    required int i29,
+    required int i30,
+    required int i31,
+    required int i32,
+    required int i33,
+    required int i34,
+    required int i35,
+    required int i36,
+    required int i37,
+    required int i38,
+    required int i39,
+    required int i40,
+    required int i41,
+    required int i42,
+    required int i43,
+    required int i44,
+    required int i45,
+    required int i46,
+    required int i47,
+    required int i48,
+    required int i49,
+    required int i50,
+    required int i51,
+    required int i52,
+    required int i53,
+    required int i54,
+    required int i55,
+    required int i56,
+    required int i57,
+    required int i58,
+    required int i59,
+    required int i60,
+    required int i61,
+    required int i62,
+    required int i63,
+    required int i64,
+    required int i65,
+    required int i66,
+    required int i67,
+    required int i68,
+    required int i69,
+    required int i70});
+typedef int fType({required int i});
+typedef int gType({int i});
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.weak.expect b/pkg/front_end/testcases/nnbd/const_is.dart.weak.expect
new file mode 100644
index 0000000..f6c3bba
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.weak.expect
@@ -0,0 +1,106 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef fType = ({required i: core::int}) → core::int;
+typedef gType = ({i: core::int}) → core::int;
+typedef bigType = ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+typedef func = (core::Object) → self::B;
+typedef t1 = (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+}
+class A2 extends core::Object {
+  synthetic constructor •() → self::A2
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A, self::A1, self::A2 {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+static field core::bool inStrongMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static const field core::bool f_is_fType = #C1;
+static const field core::bool f_is_gType = #C1;
+static const field core::bool g_is_fType = #C1;
+static const field core::bool g_is_gType = #C1;
+static const field core::bool f_is_bigType = #C2;
+static const field core::bool f1_is_t1 = #C2;
+static const field core::bool f2_is_t1 = #C2;
+static const field core::bool f3_is_t1 = #C1;
+static const field core::bool f4_is_t1 = #C1;
+static const field core::bool f5_is_t1 = #C1;
+static method f({required core::int i = #C3}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method g({core::int i = #C4}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method f1(core::int i, self::B b, core::Map<core::int, core::num> m, dynamic x, {required dynamic extraParam = #C3, required core::bool obool = #C3, required dynamic ox = #C3, required self::D ob = #C3, required core::List<core::num>? ol = #C3}) → self::B
+  return new self::B::•();
+static method f2(core::int i, self::D b, core::Map<core::int, core::int> m, (core::Object) → self::B x, {required (core::Object) → self::B ox = #C3, required self::D ob = #C3, required core::List<core::int> ol = #C3, required core::bool obool = #C3}) → self::D
+  return new self::D::•();
+static method f3(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required dynamic extraParam = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::Object obool = #C3}) → self::C
+  return new self::C::•();
+static method f4(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::bool obool = #C3, required self::A xx = #C3, required self::B yy = #C3}) → self::C
+  return new self::C::•();
+static method f5(core::int i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::B ob = #C3, required core::List<dynamic> ol = #C3, required dynamic obool = #C3}) → self::C
+  return new self::C::•();
+static method main() → dynamic {
+  self::expect(true, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(false, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int, #C2);
+  self::expect(false, #C2);
+  self::expect((#C7) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(false, #C2);
+  self::expect((#C8) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C9) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C10) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+  self::expect(true, #C1);
+  self::expect((#C11) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+  #C3 = null
+  #C4 = 1
+  #C5 = tearoff self::f
+  #C6 = tearoff self::g
+  #C7 = tearoff self::f1
+  #C8 = tearoff self::f2
+  #C9 = tearoff self::f3
+  #C10 = tearoff self::f4
+  #C11 = tearoff self::f5
+}
diff --git a/pkg/front_end/testcases/nnbd/const_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd/const_is.dart.weak.transformed.expect
new file mode 100644
index 0000000..5d2b393
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd/const_is.dart.weak.transformed.expect
@@ -0,0 +1,119 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+typedef fType = ({required i: core::int}) → core::int;
+typedef gType = ({i: core::int}) → core::int;
+typedef bigType = ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int;
+typedef func = (core::Object) → self::B;
+typedef t1 = (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B;
+class A extends core::Object {
+  synthetic constructor •() → self::A
+    : super core::Object::•()
+    ;
+}
+class A1 extends core::Object {
+  synthetic constructor •() → self::A1
+    : super core::Object::•()
+    ;
+}
+class A2 extends core::Object {
+  synthetic constructor •() → self::A2
+    : super core::Object::•()
+    ;
+}
+class B extends core::Object implements self::A, self::A1, self::A2 {
+  synthetic constructor •() → self::B
+    : super core::Object::•()
+    ;
+}
+class C extends core::Object implements self::B {
+  synthetic constructor •() → self::C
+    : super core::Object::•()
+    ;
+}
+class D extends core::Object implements self::C {
+  synthetic constructor •() → self::D
+    : super core::Object::•()
+    ;
+}
+static field core::bool inStrongMode = !(<core::int?>[] is{ForNonNullableByDefault} core::List<core::int>);
+static const field core::bool f_is_fType = #C1;
+static const field core::bool f_is_gType = #C1;
+static const field core::bool g_is_fType = #C1;
+static const field core::bool g_is_gType = #C1;
+static const field core::bool f_is_bigType = #C2;
+static const field core::bool f1_is_t1 = #C2;
+static const field core::bool f2_is_t1 = #C2;
+static const field core::bool f3_is_t1 = #C1;
+static const field core::bool f4_is_t1 = #C1;
+static const field core::bool f5_is_t1 = #C1;
+static method f({required core::int i = #C3}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method g({core::int i = #C4}) → core::int {
+  return i.{core::num::+}(1);
+}
+static method f1(core::int i, self::B b, core::Map<core::int, core::num> m, dynamic x, {required dynamic extraParam = #C3, required core::bool obool = #C3, required dynamic ox = #C3, required self::D ob = #C3, required core::List<core::num>? ol = #C3}) → self::B
+  return new self::B::•();
+static method f2(core::int i, self::D b, core::Map<core::int, core::int> m, (core::Object) → self::B x, {required (core::Object) → self::B ox = #C3, required self::D ob = #C3, required core::List<core::int> ol = #C3, required core::bool obool = #C3}) → self::D
+  return new self::D::•();
+static method f3(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required dynamic extraParam = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::Object obool = #C3}) → self::C
+  return new self::C::•();
+static method f4(core::num i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::A2 ob = #C3, required core::List<dynamic> ol = #C3, required core::bool obool = #C3, required self::A xx = #C3, required self::B yy = #C3}) → self::C
+  return new self::C::•();
+static method f5(core::int i, self::A b, core::Map<core::Object, core::Object> m, dynamic x, {required dynamic ox = #C3, required self::B ob = #C3, required core::List<dynamic> ol = #C3, required dynamic obool = #C3}) → self::C
+  return new self::C::•();
+static method main() → dynamic {
+  self::expect(true, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C5) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({required i: core::int}) → core::int, #C1);
+  self::expect(true, #C1);
+  self::expect((#C6) is{ForNonNullableByDefault} ({i: core::int}) → core::int, #C1);
+  self::expect(false, #C2);
+  self::expect((#C5) is{ForNonNullableByDefault} ({required i1: core::int, required i10: core::int, required i11: core::int, required i12: core::int, required i13: core::int, required i14: core::int, required i15: core::int, required i16: core::int, required i17: core::int, required i18: core::int, required i19: core::int, required i2: core::int, required i20: core::int, required i21: core::int, required i22: core::int, required i23: core::int, required i24: core::int, required i25: core::int, required i26: core::int, required i27: core::int, required i28: core::int, required i29: core::int, required i3: core::int, required i30: core::int, required i31: core::int, required i32: core::int, required i33: core::int, required i34: core::int, required i35: core::int, required i36: core::int, required i37: core::int, required i38: core::int, required i39: core::int, required i4: core::int, required i40: core::int, required i41: core::int, required i42: core::int, required i43: core::int, required i44: core::int, required i45: core::int, required i46: core::int, required i47: core::int, required i48: core::int, required i49: core::int, required i5: core::int, required i50: core::int, required i51: core::int, required i52: core::int, required i53: core::int, required i54: core::int, required i55: core::int, required i56: core::int, required i57: core::int, required i58: core::int, required i59: core::int, required i6: core::int, required i60: core::int, required i61: core::int, required i62: core::int, required i63: core::int, required i64: core::int, required i65: core::int, required i66: core::int, required i67: core::int, required i68: core::int, required i69: core::int, required i7: core::int, required i70: core::int, required i8: core::int, required i9: core::int}) → core::int, #C2);
+  self::expect(false, #C2);
+  self::expect((#C7) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(false, #C2);
+  self::expect((#C8) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C2);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C9) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+  self::expect(!self::inStrongMode, #C1);
+  self::expect((#C10) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+  self::expect(true, #C1);
+  self::expect((#C11) is{ForNonNullableByDefault} (core::int, self::B, core::Map<core::int, core::num>, dynamic, {required ob: self::B, required obool: core::bool, required ol: core::List<core::num>, required ox: dynamic}) → self::B, #C1);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+constants  {
+  #C1 = true
+  #C2 = false
+  #C3 = null
+  #C4 = 1
+  #C5 = tearoff self::f
+  #C6 = tearoff self::g
+  #C7 = tearoff self::f1
+  #C8 = tearoff self::f2
+  #C9 = tearoff self::f3
+  #C10 = tearoff self::f4
+  #C11 = tearoff self::f5
+}
+
+Extra constant evaluation status:
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:157:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:159:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:161:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:163:12 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:165:12 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:168:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:170:13 -> BoolConstant(false)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:172:13 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:174:13 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:176:13 -> BoolConstant(true)
+Extra constant evaluation: evaluated: 56, effectively constant: 10
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is.dart b/pkg/front_end/testcases/nnbd_mixed/const_is.dart
new file mode 100644
index 0000000..9649a2d
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is.dart
@@ -0,0 +1,27 @@
+// 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.
+
+// Test derived from language/nnbd/subtyping/function_type_bounds_weak_test
+
+import 'const_is_lib.dart';
+
+main() {
+  // void fn<T extends Object>() is void Function<T extends Object?>()
+  // Should pass with weak checking because when the nullability information on
+  // Object and Object? are erased the type bounds are equivalent.
+  expect(true, fnWithNonNullObjectBound is fnTypeWithNullableObjectBound);
+  const test1 = fnWithNonNullObjectBound is fnTypeWithNullableObjectBound;
+  expect(true, test1);
+
+  // void fn<T extends Null>() is void Function<T extends Never>()
+  // Should pass with weak checking because because Null becomes equivalent to
+  // the bottom type.
+  expect(true, fnWithNullBound is fnTypeWithNeverBound);
+  const test2 = fnWithNullBound is fnTypeWithNeverBound;
+  expect(true, test2);
+}
+
+expect(expected, actual) {
+  if (expected != actual) throw "Expected $expected, actual $actual";
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline.expect b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline.expect
new file mode 100644
index 0000000..2b71bf0
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline.expect
@@ -0,0 +1,4 @@
+import 'const_is_lib.dart';
+
+main() {}
+expect(expected, actual) {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline_modelled.expect b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline_modelled.expect
new file mode 100644
index 0000000..0d90c13
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.textual_outline_modelled.expect
@@ -0,0 +1,4 @@
+import 'const_is_lib.dart';
+
+expect(expected, actual) {}
+main() {}
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.expect
new file mode 100644
index 0000000..a139d60
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.expect
@@ -0,0 +1,33 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///const_is_lib.dart";
+
+static method main() → dynamic {
+  self::expect(true, (#C1) is{ForNonNullableByDefault} <T extends core::Object? = core::Object?>() → void);
+  self::expect(true, #C2);
+  self::expect(true, (#C3) is{ForNonNullableByDefault} <T extends Never = dynamic>() → void);
+  self::expect(true, #C2);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef fnTypeWithNullableObjectBound = <T extends core::Object? = core::Object?>() → void;
+typedef fnTypeWithNeverBound = <T extends Never = dynamic>() → void;
+static method fnWithNonNullObjectBound<T extends core::Object = core::Object>() → void
+  return null;
+static method fnWithNullBound<T extends core::Null? = core::Null?>() → void
+  return null;
+
+constants  {
+  #C1 = tearoff self2::fnWithNonNullObjectBound
+  #C2 = true
+  #C3 = tearoff self2::fnWithNullBound
+}
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.transformed.expect
new file mode 100644
index 0000000..9c0d806
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is.dart.weak.transformed.expect
@@ -0,0 +1,38 @@
+library /*isNonNullableByDefault*/;
+import self as self;
+import "dart:core" as core;
+
+import "org-dartlang-testcase:///const_is_lib.dart";
+
+static method main() → dynamic {
+  self::expect(true, (#C1) is{ForNonNullableByDefault} <T extends core::Object? = core::Object?>() → void);
+  self::expect(true, #C2);
+  self::expect(true, (#C3) is{ForNonNullableByDefault} <T extends Never = dynamic>() → void);
+  self::expect(true, #C2);
+}
+static method expect(dynamic expected, dynamic actual) → dynamic {
+  if(!expected.{core::Object::==}(actual))
+    throw "Expected ${expected}, actual ${actual}";
+}
+
+library /*isNonNullableByDefault*/;
+import self as self2;
+import "dart:core" as core;
+
+typedef fnTypeWithNullableObjectBound = <T extends core::Object? = core::Object?>() → void;
+typedef fnTypeWithNeverBound = <T extends Never = dynamic>() → void;
+static method fnWithNonNullObjectBound<T extends core::Object = core::Object>() → void
+  return null;
+static method fnWithNullBound<T extends core::Null? = core::Null?>() → void
+  return null;
+
+constants  {
+  #C1 = tearoff self2::fnWithNonNullObjectBound
+  #C2 = true
+  #C3 = tearoff self2::fnWithNullBound
+}
+
+Extra constant evaluation status:
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:13:41 -> BoolConstant(true)
+Evaluated: IsExpression @ org-dartlang-testcase:///const_is.dart:20:32 -> BoolConstant(true)
+Extra constant evaluation: evaluated: 14, effectively constant: 2
diff --git a/pkg/front_end/testcases/nnbd_mixed/const_is_lib.dart b/pkg/front_end/testcases/nnbd_mixed/const_is_lib.dart
new file mode 100644
index 0000000..e3d0d48
--- /dev/null
+++ b/pkg/front_end/testcases/nnbd_mixed/const_is_lib.dart
@@ -0,0 +1,12 @@
+// 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.
+
+/// A null safe library of helper methods to construct types and values
+/// containing non-nullable and nullable (question ?) types.
+
+typedef fnTypeWithNullableObjectBound = void Function<T extends Object?>();
+typedef fnTypeWithNeverBound = void Function<T extends Never>();
+
+void fnWithNonNullObjectBound<T extends Object>() => null;
+void fnWithNullBound<T extends Null>() => null;
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.expect
index 4fa35c5..48c54ae 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.expect
@@ -7,10 +7,10 @@
 
 static method main() → void {
   core::Null? nil;
-  iss::x = null as{TypeError} Never;
-  iss::x = nil as{TypeError} Never;
-  iss::takesNever(null as{TypeError} Never);
-  iss::takesNever(nil as{TypeError} Never);
+  iss::x = null;
+  iss::x = nil;
+  iss::takesNever(null);
+  iss::takesNever(nil);
   iss::takesTakesNull(#C1);
   iss::f = (Never* x) → core::Null? {};
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.transformed.expect
index 4fa35c5..48c54ae 100644
--- a/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/issue41435.dart.weak.transformed.expect
@@ -7,10 +7,10 @@
 
 static method main() → void {
   core::Null? nil;
-  iss::x = null as{TypeError} Never;
-  iss::x = nil as{TypeError} Never;
-  iss::takesNever(null as{TypeError} Never);
-  iss::takesNever(nil as{TypeError} Never);
+  iss::x = null;
+  iss::x = nil;
+  iss::takesNever(null);
+  iss::takesNever(nil);
   iss::takesTakesNull(#C1);
   iss::f = (Never* x) → core::Null? {};
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.expect
index a1b69ec..973cfd4 100644
--- a/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.expect
@@ -75,10 +75,8 @@
   abstract member-signature method method4c([core::int? a = #C1, core::int? b = #C1]) → core::int?; -> opt::LegacyClass::method4c
   abstract member-signature method method5a(core::int a, {core::int b = #C1}) → core::int; -> opt::LegacyClass::method5a
   abstract member-signature method method5b({core::int a = #C1, core::int b = #C1}) → core::int; -> opt::LegacyClass::method5b
-  abstract member-signature method method5c({core::int a = #C1, core::int b = #C1}) → core::int; -> opt::LegacyClass::method5c
   abstract member-signature method method6a(core::int? a, {core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6a
   abstract member-signature method method6b({core::int? a = #C1, core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6b
-  abstract member-signature method method6c({core::int? a = #C1, core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6c
   abstract member-signature get getter1() → core::int; -> opt::LegacyClass::getter1
   abstract member-signature get getter2() → core::int?; -> opt::LegacyClass::getter2
   abstract member-signature get _identityHashCode() → core::int; -> core::Object::_identityHashCode
diff --git a/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.transformed.expect
index a1b69ec..973cfd4 100644
--- a/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/member_inheritance_from_opt_out.dart.weak.transformed.expect
@@ -75,10 +75,8 @@
   abstract member-signature method method4c([core::int? a = #C1, core::int? b = #C1]) → core::int?; -> opt::LegacyClass::method4c
   abstract member-signature method method5a(core::int a, {core::int b = #C1}) → core::int; -> opt::LegacyClass::method5a
   abstract member-signature method method5b({core::int a = #C1, core::int b = #C1}) → core::int; -> opt::LegacyClass::method5b
-  abstract member-signature method method5c({core::int a = #C1, core::int b = #C1}) → core::int; -> opt::LegacyClass::method5c
   abstract member-signature method method6a(core::int? a, {core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6a
   abstract member-signature method method6b({core::int? a = #C1, core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6b
-  abstract member-signature method method6c({core::int? a = #C1, core::int? b = #C1}) → core::int?; -> opt::LegacyClass::method6c
   abstract member-signature get getter1() → core::int; -> opt::LegacyClass::getter1
   abstract member-signature get getter2() → core::int?; -> opt::LegacyClass::getter2
   abstract member-signature get _identityHashCode() → core::int; -> core::Object::_identityHashCode
diff --git a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect
index 3c9a505..1977f90 100644
--- a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.expect
@@ -73,19 +73,19 @@
   inferredLocalNever = localNever;
   localNever = self::optOutNever;
   self::optOutNever = self::optOutNever;
-  nev::optInNever = self::optOutNever as{TypeError} Never;
+  nev::optInNever = self::optOutNever;
   localNull = self::optOutNever;
   self::inferredOptOutNever = self::optOutNever;
   inferredLocalNever = self::optOutNever;
   localNever = nev::optInNever;
   self::optOutNever = nev::optInNever;
-  nev::optInNever = nev::optInNever as{TypeError} Never;
+  nev::optInNever = nev::optInNever;
   localNull = nev::optInNever;
   self::inferredOptOutNever = nev::optInNever;
   inferredLocalNever = nev::optInNever;
   localNever = localNull;
   self::optOutNever = localNull;
-  nev::optInNever = localNull as{TypeError} Never;
+  nev::optInNever = localNull;
   localNull = localNull;
   self::inferredOptOutNever = localNull;
   inferredLocalNever = localNull;
@@ -104,7 +104,7 @@
   self::throws(() → core::Null? => self::optOutNever = nev::throwing());
   self::throws(() → core::Null? => localNever = nev::throwing());
   self::throws(() → core::Null? => self::optOutNever = nev::throwing());
-  self::throws(() → core::Null? => nev::optInNever = nev::throwing() as{TypeError} Never);
+  self::throws(() → core::Null? => nev::optInNever = nev::throwing());
   self::throws(() → core::Null? => self::inferredOptOutNever = nev::throwing());
   self::throws(() → core::Null? => inferredLocalNever = nev::throwing());
 }
@@ -119,14 +119,6 @@
 }
 
 library /*isNonNullableByDefault*/;
-//
-// Problems in library:
-//
-// pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be returned from a function with return type 'Null'.
-//  - 'Type' is from 'dart:core'.
-//   Null get nullProperty => Null;
-//                            ^
-//
 import self as nev;
 import "dart:core" as core;
 import "dart:_internal" as _in;
@@ -148,10 +140,7 @@
   method nullMethod(core::Null? value) → core::Null?
     return value;
   get nullProperty() → core::Null?
-    return let final<BottomType> #t2 = invalid-expression "pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart:19:28: Error: A value of type 'Type' can't be returned from a function with return type 'Null'.
- - 'Type' is from 'dart:core'.
-  Null get nullProperty => Null;
-                           ^" in core::Null? as{TypeError,ForNonNullableByDefault} core::Null?;
+    return null;
   set nullProperty(core::Null? value) → void {}
 }
 static field Never optInNever = self::optOutNever;
diff --git a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.transformed.expect
index bf726fb..1977f90 100644
--- a/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/never_opt_out.dart.weak.transformed.expect
@@ -1,16 +1,70 @@
 library;
 import self as self;
-import "dart:core" as core;
 import "never_opt_out_lib.dart" as nev;
+import "dart:core" as core;
 
 import "org-dartlang-testcase:///never_opt_out_lib.dart";
 
+class B extends nev::A {
+  field core::Null? neverField = null;
+  field core::Null? nullField = null;
+  synthetic constructor •() → self::B*
+    : super nev::A::•()
+    ;
+  method neverMethod(core::Null? value) → core::Null?
+    return value;
+  get neverProperty() → core::Null?
+    return null;
+  set neverProperty(core::Null? value) → void {}
+  method nullMethod(core::Null? value) → core::Null?
+    return value;
+  get nullProperty() → core::Null?
+    return null;
+  set nullProperty(core::Null? value) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
+class C extends nev::A {
+  field Never* neverField = null;
+  field Never* nullField = null;
+  synthetic constructor •() → self::C*
+    : super nev::A::•()
+    ;
+  method neverMethod(Never* value) → Never*
+    return value;
+  get neverProperty() → Never*
+    return null;
+  set neverProperty(Never* value) → void {}
+  method nullMethod(Never* value) → Never*
+    return value;
+  get nullProperty() → Never*
+    return null;
+  set nullProperty(Never* value) → void {}
+  abstract member-signature get _identityHashCode() → core::int*; -> core::Object::_identityHashCode
+  abstract member-signature method _instanceOf(dynamic instantiatorTypeArguments, dynamic functionTypeArguments, dynamic type) → core::bool*; -> core::Object::_instanceOf
+  abstract member-signature method _simpleInstanceOf(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOf
+  abstract member-signature method _simpleInstanceOfTrue(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfTrue
+  abstract member-signature method _simpleInstanceOfFalse(dynamic type) → core::bool*; -> core::Object::_simpleInstanceOfFalse
+  abstract member-signature operator ==(dynamic other) → core::bool*; -> core::Object::==
+  abstract member-signature get hashCode() → core::int*; -> core::Object::hashCode
+  abstract member-signature method toString() → core::String*; -> core::Object::toString
+  abstract member-signature method noSuchMethod(core::Invocation* invocation) → dynamic; -> core::Object::noSuchMethod
+  abstract member-signature get runtimeType() → core::Type*; -> core::Object::runtimeType
+}
 static field Never* optOutNever;
-static field core::Null? inferredOptOutNever = nev::optInNever;
+static field dynamic inferredOptOutNever = nev::optInNever;
 static method main() → dynamic {
   Never* localNever = null;
   core::Null? localNull = null;
-  Never inferredLocalNever = nev::optInNever;
+  dynamic inferredLocalNever = nev::optInNever;
   localNever = localNever;
   self::optOutNever = localNever;
   nev::optInNever = localNever;
@@ -31,28 +85,28 @@
   inferredLocalNever = nev::optInNever;
   localNever = localNull;
   self::optOutNever = localNull;
-  nev::optInNever = localNull as{TypeError} Never;
+  nev::optInNever = localNull;
   localNull = localNull;
   self::inferredOptOutNever = localNull;
-  inferredLocalNever = localNull as{TypeError} Never;
-  localNever = self::inferredOptOutNever;
-  self::optOutNever = self::inferredOptOutNever;
-  nev::optInNever = self::inferredOptOutNever as{TypeError} Never;
-  localNull = self::inferredOptOutNever;
+  inferredLocalNever = localNull;
+  localNever = self::inferredOptOutNever as{TypeError,ForDynamic} Never*;
+  self::optOutNever = self::inferredOptOutNever as{TypeError,ForDynamic} Never*;
+  nev::optInNever = self::inferredOptOutNever as{TypeError,ForDynamic} Never;
+  localNull = self::inferredOptOutNever as{TypeError,ForDynamic} core::Null?;
   self::inferredOptOutNever = self::inferredOptOutNever;
-  inferredLocalNever = self::inferredOptOutNever as{TypeError} Never;
-  localNever = inferredLocalNever;
-  self::optOutNever = inferredLocalNever;
-  nev::optInNever = inferredLocalNever;
-  localNull = inferredLocalNever;
+  inferredLocalNever = self::inferredOptOutNever;
+  localNever = inferredLocalNever as{TypeError,ForDynamic} Never*;
+  self::optOutNever = inferredLocalNever as{TypeError,ForDynamic} Never*;
+  nev::optInNever = inferredLocalNever as{TypeError,ForDynamic} Never;
+  localNull = inferredLocalNever as{TypeError,ForDynamic} core::Null?;
   self::inferredOptOutNever = inferredLocalNever;
   inferredLocalNever = inferredLocalNever;
-  self::throws(() → Never => self::optOutNever = nev::throwing());
-  self::throws(() → Never => localNever = nev::throwing());
-  self::throws(() → Never => self::optOutNever = nev::throwing());
-  self::throws(() → Never => nev::optInNever = nev::throwing());
-  self::throws(() → Never => self::inferredOptOutNever = nev::throwing());
-  self::throws(() → Never => inferredLocalNever = nev::throwing());
+  self::throws(() → core::Null? => self::optOutNever = nev::throwing());
+  self::throws(() → core::Null? => localNever = nev::throwing());
+  self::throws(() → core::Null? => self::optOutNever = nev::throwing());
+  self::throws(() → core::Null? => nev::optInNever = nev::throwing());
+  self::throws(() → core::Null? => self::inferredOptOutNever = nev::throwing());
+  self::throws(() → core::Null? => inferredLocalNever = nev::throwing());
 }
 static method throws(() →* void f) → dynamic {
   try {
@@ -66,10 +120,29 @@
 
 library /*isNonNullableByDefault*/;
 import self as nev;
+import "dart:core" as core;
+import "dart:_internal" as _in;
 import "never_opt_out.dart" as self;
 
 import "org-dartlang-testcase:///never_opt_out.dart";
 
+class A extends core::Object {
+  field Never neverField = throw "Should not reach here";
+  field core::Null? nullField = null;
+  synthetic constructor •() → nev::A
+    : super core::Object::•()
+    ;
+  method neverMethod(Never value) → Never
+    return let final Never #t1 = value in throw new _in::ReachabilityError::•("`null` encountered as the result from expression with type `Never`.");
+  get neverProperty() → Never
+    return throw "Should not reach here";
+  set neverProperty(Never value) → void {}
+  method nullMethod(core::Null? value) → core::Null?
+    return value;
+  get nullProperty() → core::Null?
+    return null;
+  set nullProperty(core::Null? value) → void {}
+}
 static field Never optInNever = self::optOutNever;
 static method throwing() → Never
   return throw "Never!";
diff --git a/pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart b/pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart
index 06c5c16..a519e50 100644
--- a/pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart
+++ b/pkg/front_end/testcases/nnbd_mixed/never_opt_out_lib.dart
@@ -16,6 +16,6 @@
 
   Null nullField = null;
   Null nullMethod(Null value) => value;
-  Null get nullProperty => Null;
+  Null get nullProperty => null;
   void set nullProperty(Null value) {}
 }
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
index 3a8e857..919f10f 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.expect
@@ -256,7 +256,7 @@
   uns::unnecessaryNullAwareAccess(() → core::Null? => null);
   self::throws(() → dynamic => uns::callReturningNever(() → <BottomType>=> throw "foo"), (core::Object* e) → core::bool* => e.{core::Object::==}("foo"));
   () →* core::Null? f = () → core::Null? => null;
-  self::throws(() → dynamic => uns::callReturningNever(f as{TypeError} () → Never));
+  self::throws(() → dynamic => uns::callReturningNever(f));
   uns::switchOnEnum(#C3);
   uns::switchOnEnum(#C6);
   self::throws(() → dynamic => uns::switchOnEnum(null));
diff --git a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
index eacb84d..908eb54 100644
--- a/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
+++ b/pkg/front_end/testcases/nnbd_mixed/unsound_checks.dart.weak.transformed.expect
@@ -256,7 +256,7 @@
   uns::unnecessaryNullAwareAccess(() → core::Null? => null);
   self::throws(() → dynamic => uns::callReturningNever(() → <BottomType>=> throw "foo"), (core::Object* e) → core::bool* => e.{core::Object::==}("foo"));
   () →* core::Null? f = () → core::Null? => null;
-  self::throws(() → dynamic => uns::callReturningNever(f as{TypeError} () → Never));
+  self::throws(() → dynamic => uns::callReturningNever(f));
   uns::switchOnEnum(#C3);
   uns::switchOnEnum(#C6);
   self::throws(() → dynamic => uns::switchOnEnum(null));
@@ -639,4 +639,4 @@
 Evaluated: VariableGet @ org-dartlang-testcase:///unsound_checks_lib.dart:39:56 -> IntConstant(42)
 Evaluated: VariableGet @ org-dartlang-testcase:///unsound_checks_lib.dart:134:5 -> IntConstant(0)
 Evaluated: VariableGet @ org-dartlang-testcase:///unsound_checks_lib.dart:134:5 -> IntConstant(0)
-Extra constant evaluation: evaluated: 720, effectively constant: 18
+Extra constant evaluation: evaluated: 719, effectively constant: 18
diff --git a/pkg/front_end/testcases/weak.status b/pkg/front_end/testcases/weak.status
index 689551d..e652cfc 100644
--- a/pkg/front_end/testcases/weak.status
+++ b/pkg/front_end/testcases/weak.status
@@ -73,7 +73,6 @@
 nnbd_mixed/issue41567: TypeCheckError
 nnbd_mixed/messages_with_types_opt_in: TypeCheckError
 nnbd_mixed/messages_with_types_opt_out: TypeCheckError
-nnbd_mixed/never_opt_out: TypeCheckError
 value_class/simple: RuntimeError # Expected
 value_class/value_extends_non_value: RuntimeError # Expected
 value_class/value_implements_non_value: RuntimeError # Expected
diff --git a/pkg/kernel/lib/src/types.dart b/pkg/kernel/lib/src/types.dart
index 88e6940..2ab1891 100644
--- a/pkg/kernel/lib/src/types.dart
+++ b/pkg/kernel/lib/src/types.dart
@@ -482,9 +482,9 @@
         return const IsSubtypeOf.never();
       }
     }
-    List<NamedType> sNamed = s.namedParameters;
-    List<NamedType> tNamed = t.namedParameters;
-    if (sNamed.isNotEmpty || tNamed.isNotEmpty) {
+    List<NamedType> sNamedParameters = s.namedParameters;
+    List<NamedType> tNamedParameters = t.namedParameters;
+    if (sNamedParameters.isNotEmpty || tNamedParameters.isNotEmpty) {
       // Rule 16, the number of positional parameters must be the same.
       if (sPositional.length != tPositional.length) {
         return const IsSubtypeOf.never();
@@ -497,17 +497,46 @@
       // [s]. Also, for the intersection, the type of the parameter of [t] must
       // be a subtype of the type of the parameter of [s].
       int sCount = 0;
-      for (int tCount = 0; tCount < tNamed.length; tCount++) {
-        String name = tNamed[tCount].name;
-        for (; sCount < sNamed.length; sCount++) {
-          if (sNamed[sCount].name == name) break;
+      for (int tCount = 0; tCount < tNamedParameters.length; tCount++) {
+        NamedType tNamedParameter = tNamedParameters[tCount];
+        String name = tNamedParameter.name;
+        NamedType sNamedParameter;
+        for (; sCount < sNamedParameters.length; sCount++) {
+          sNamedParameter = sNamedParameters[sCount];
+          if (sNamedParameter.name == name) {
+            break;
+          } else if (sNamedParameter.isRequired) {
+            /// From the NNBD spec: For each j such that r0j is required, then
+            /// there exists an i in n+1...q such that xj = yi, and r1i is
+            /// required
+            result =
+                result.and(const IsSubtypeOf.onlyIfIgnoringNullabilities());
+          }
         }
-        if (sCount == sNamed.length) return const IsSubtypeOf.never();
+        if (sCount == sNamedParameters.length) return const IsSubtypeOf.never();
+        // Increment [sCount] so we don't check [sNamedParameter] again in the
+        // loop above or below and assume it is an extra (unmatched) parameter.
+        sCount++;
         result = result.and(types.performNullabilityAwareSubtypeCheck(
-            tNamed[tCount].type, sNamed[sCount].type));
+            tNamedParameter.type, sNamedParameter.type));
         if (!result.isSubtypeWhenIgnoringNullabilities()) {
           return const IsSubtypeOf.never();
         }
+
+        /// From the NNBD spec: For each j such that r0j is required, then there
+        /// exists an i in n+1...q such that xj = yi, and r1i is required
+        if (sNamedParameter.isRequired && !tNamedParameter.isRequired) {
+          result = result.and(const IsSubtypeOf.onlyIfIgnoringNullabilities());
+        }
+      }
+      for (; sCount < sNamedParameters.length; sCount++) {
+        NamedType sNamedParameter = sNamedParameters[sCount];
+        if (sNamedParameter.isRequired) {
+          /// From the NNBD spec: For each j such that r0j is required, then
+          /// there exists an i in n+1...q such that xj = yi, and r1i is
+          /// required
+          result = result.and(const IsSubtypeOf.onlyIfIgnoringNullabilities());
+        }
       }
     }
     return result.and(new IsSubtypeOf.basedSolelyOnNullabilities(s, t));
@@ -899,7 +928,7 @@
         return const IsSubtypeOf.always();
       }
       if (t.nullability == Nullability.nonNullable) {
-        return const IsSubtypeOf.never();
+        return const IsSubtypeOf.onlyIfIgnoringNullabilities();
       }
       throw new StateError(
           "Unexpected nullability '$t.nullability' of type Never");