Add test for inference solving T? = dynamic.
See https://github.com/dart-lang/language/issues/1035
Change-Id: Ieb258a020d8212f5488cc3d73978b8132223353d
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/151760
Commit-Queue: Lasse R.H. Nielsen <lrn@google.com>
Reviewed-by: Leaf Petersen <leafp@google.com>
diff --git a/tests/language/inference/dynamic_nullable_test.dart b/tests/language/inference/dynamic_nullable_test.dart
new file mode 100644
index 0000000..6bcb121
--- /dev/null
+++ b/tests/language/inference/dynamic_nullable_test.dart
@@ -0,0 +1,81 @@
+// 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.
+
+import "package:expect/expect.dart";
+
+// Tests that inference can solve for T? ~ dynamic or void.
+
+class C<T extends Object> {
+ final T? value;
+ const C(this.value);
+ C.list(List<T?> list) : value = list.first;
+ void set nonNullValue(T value) {}
+}
+
+List<T> foo<T extends Object>(T? value) => [value!];
+
+List<T> bar<T extends Object>(List<T?> value) => [
+ for (var element in value)
+ if (element != null) element
+ ];
+
+extension Ext<T extends Object> on List<T?> {
+ List<T> whereNotNull() => [
+ for (var element in this)
+ if (element != null) element
+ ];
+}
+
+main() {
+ {
+ // Testing for dynamic.
+ const dynamic o = 42;
+
+ var c = const C(o);
+ var f = foo(o);
+ var l = [o].whereNotNull();
+
+ c.expectStaticType<Exactly<C<Object>>>();
+ Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>.
+ c.nonNullValue = Object(); // And supertype.
+
+ f.expectStaticType<Exactly<List<Object>>>();
+ Expect.type<List<Object>>(f); // Run-time type is subtype of List<Object>.
+ f[0] = Object(); // And supertype.
+
+ l.expectStaticType<Exactly<List<Object>>>();
+ Expect.type<List<Object>>(l); // Run-time type is subtype of List<Object>.
+ l[0] = Object(); // And supertype.
+ }
+
+ {
+ // Testing for void
+ List<void> o = <void>[42];
+
+ var c = C.list(o);
+ var f = bar(o);
+ var l = o.whereNotNull;
+
+ c.expectStaticType<Exactly<C<Object>>>();
+ Expect.type<C<Object>>(c); // Run-time type is subtype of C<Object>.
+ c.nonNullValue = Object(); // And supertype.
+
+ f.expectStaticType<Exactly<List<Object>>>();
+ Expect.type<List<Object>>(f); // Run-time type is subtype of List<Object>.
+ f[0] = Object(); // And supertype.
+
+ l.expectStaticType<Exactly<List<Object>>>();
+ Expect.type<List<Object>>(l); // Run-time type is subtype of List<Object>.
+ l[0] = Object(); // And supertype.
+ }
+}
+
+// Captures and checks static type of expression.
+extension TypeCheck<T> on T {
+ T expectStaticType<R extends Exactly<T>>() {
+ return this;
+ }
+}
+
+typedef Exactly<T> = T Function(T);