[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");