Skip to content

Commit 8c5fea8

Browse files
committed
Fixes #996: new tests for i-2-b and least-and-greatest-closures added.
1 parent 06cdf95 commit 8c5fea8

File tree

5 files changed

+215
-1
lines changed

5 files changed

+215
-1
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
3+
* for details. All rights reserved. Use of this source code is governed by a
4+
* BSD-style license that can be found in the LICENSE file.
5+
*/
6+
/**
7+
* @assertion The definitions of least and greatest closure are changed in null
8+
* safe libraries to substitute [Never] in positions where previously [Null
9+
* would have been substituted, and [Object?] in positions where previously
10+
* [Object] or [dynamic] would have been substituted.
11+
* @description Check statically that correct type is substituted for generic
12+
* [void Function<T>()] typedef.
13+
* @note Read more about the least and greatest closure test template:
14+
* https://github.com/dart-lang/co19/issues/575#issuecomment-613542349
15+
*
16+
17+
*/
18+
// SharedOptions=--enable-experiment=generic-metadata
19+
20+
import "../../Utils/expect.dart";
21+
22+
typedef check = void Function<T>();
23+
24+
void main() {
25+
void f(check Function<T>() g) => g();
26+
27+
// Verify that we can call the function with the specified arguments.
28+
f(<T>() => captureTypeArgument()..call());
29+
30+
// Verify that a couple of wrong argument lists are rejected.
31+
f(<T>() => captureTypeArgument()..call(throw 1));
32+
// ^
33+
// [analyzer] unspecified
34+
// [cfe] unspecified
35+
36+
f(<T>() => captureTypeArgument()..call('Hello'));
37+
// ^
38+
// [analyzer] unspecified
39+
// [cfe] unspecified
40+
41+
f(<T>() => captureTypeArgument()..call(arg: 'Hello'));
42+
// ^
43+
// [analyzer] unspecified
44+
// [cfe] unspecified
45+
46+
// Verify that the return type is `void`: Returned value not usable,
47+
// not even to access a member of `Object`.
48+
f(<T>() => captureTypeArgument()..call().toString());
49+
// ^
50+
// [analyzer] unspecified
51+
// [cfe] unspecified
52+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
3+
* for details. All rights reserved. Use of this source code is governed by a
4+
* BSD-style license that can be found in the LICENSE file.
5+
*/
6+
/**
7+
* @assertion Instantiate to bound then computes an actual type argument list
8+
* for [G] as follows:
9+
*
10+
* Let [Ui],[1] be [Si], for all [i] in [1 .. k]. (This is the "current value"
11+
* of the bound for type variable [i], at step [1]; in general we will
12+
* consider the current step, [m], and use data for that step, e.g., the bound
13+
* [Ui],[m], to compute the data for step [m + 1]).
14+
*
15+
* Let [-->m] be a relation among the type variables [X1 .. Xk] such that
16+
* [Xp -->m Xq] iff [Xq] occurs in [Up],[m] (so each type variable is related
17+
* to, that is, depends on, every type variable in its bound, possibly
18+
* including itself). Let [==>m] be the transitive closure of [-->m]. For each
19+
* [m], let [Ui],[m+1], for [i] in [1 .. k], be determined by the following
20+
* iterative process:
21+
*
22+
* 1. If there exists a [j] in [1 .. k] such that [Xj ==>m X0j] (that is, if
23+
* the dependency graph has a cycle) let [M1 .. Mp] be the strongly connected
24+
* components (SCCs) with respect to [-->m] (that is, the maximal subsets of
25+
* [X1 .. Xk] where every pair of variables in each subset are related in both
26+
* directions by [==>m]; note that the SCCs are pairwise disjoint; also, they
27+
* are uniquely defined up to reordering, and the order does not matter). Let
28+
* [M] be the union of [M1 .. Mp] (that is, all variables that participate in
29+
* a dependency cycle). Let [i] be in [1 .. k]. If [Xi] does not belong to [M]
30+
* then [Ui,m+1 = Ui,m]. Otherwise there exists a [q] such that [Xi] belongs
31+
* to [Mq]; [Ui,m+1] is then obtained from [Ui,m] by replacing every covariant
32+
* occurrence of a variable in [Mq] by [dynamic], and replacing every
33+
* contravariant occurrence of a variable in [Mq] by [Null].
34+
*
35+
* 2. Otherwise, (if no dependency cycle exists) let [j] be the lowest number
36+
* such that [Xj] occurs in [Up,m] for some [p] and [Xj -/->m Xq] for all [q]
37+
* in [1..k] (that is, [Uj,m] is closed, that is, the current bound of [Xj]
38+
* does not contain any type variables; but [Xj] is being depended on by the
39+
* bound of some other type variable). Then, for all [i] in [1 .. k], [Ui,m+1]
40+
* is obtained from [Ui,m] by replacing every covariant occurrence of [Xj] by
41+
* [Uj,m], and replacing every contravariant occurrence of [Xj] by [Null].
42+
*
43+
* 3. Otherwise, (when no dependencies exist) terminate with the result
44+
* [<U1,m ..., Uk,m>].
45+
* @description Checks that function type argument cannot have reference to
46+
* itself.
47+
48+
*/
49+
// SharedOptions=--enable-experiment=generic-metadata
50+
51+
typedef FUNC1<T> = void Function<T1 extends FUNC1<T>>();
52+
// ^^^^^
53+
// [analyzer] unspecified
54+
// [cfe] unspecified
55+
56+
typedef FUNC2<T> = T2 Function<T2 extends FUNC2<T>>();
57+
// ^^^^^
58+
// [analyzer] unspecified
59+
// [cfe] unspecified
60+
61+
main() {}
Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
/*
2+
* Copyright (c) 2018, the Dart project authors. Please see the AUTHORS file
3+
* for details. All rights reserved. Use of this source code is governed by a
4+
* BSD-style license that can be found in the LICENSE file.
5+
*/
6+
/**
7+
* @assertion Instantiate to bound then computes an actual type argument list
8+
* for [G] as follows:
9+
*
10+
* Let [Ui],[1] be [Si], for all [i] in [1 .. k]. (This is the "current value"
11+
* of the bound for type variable [i], at step [1]; in general we will
12+
* consider the current step, [m], and use data for that step, e.g., the bound
13+
* [Ui],[m], to compute the data for step [m + 1]).
14+
*
15+
* Let [-->m] be a relation among the type variables [X1 .. Xk] such that
16+
* [Xp -->m Xq] iff [Xq] occurs in [Up],[m] (so each type variable is related
17+
* to, that is, depends on, every type variable in its bound, possibly
18+
* including itself). Let [==>m] be the transitive closure of [-->m]. For each
19+
* [m], let [Ui],[m+1], for [i] in [1 .. k], be determined by the following
20+
* iterative process:
21+
*
22+
* 1. If there exists a [j] in [1 .. k] such that [Xj ==>m X0j] (that is, if
23+
* the dependency graph has a cycle) let [M1 .. Mp] be the strongly connected
24+
* components (SCCs) with respect to [-->m] (that is, the maximal subsets of
25+
* [X1 .. Xk] where every pair of variables in each subset are related in both
26+
* directions by [==>m]; note that the SCCs are pairwise disjoint; also, they
27+
* are uniquely defined up to reordering, and the order does not matter). Let
28+
* [M] be the union of [M1 .. Mp] (that is, all variables that participate in
29+
* a dependency cycle). Let [i] be in [1 .. k]. If [Xi] does not belong to [M]
30+
* then [Ui,m+1 = Ui,m]. Otherwise there exists a [q] such that [Xi] belongs
31+
* to [Mq]; [Ui,m+1] is then obtained from [Ui,m] by replacing every covariant
32+
* occurrence of a variable in [Mq] by [dynamic], and replacing every
33+
* contravariant occurrence of a variable in [Mq] by [Null].
34+
*
35+
* 2. Otherwise, (if no dependency cycle exists) let [j] be the lowest number
36+
* such that [Xj] occurs in [Up,m] for some [p] and [Xj -/->m Xq] for all [q]
37+
* in [1..k] (that is, [Uj,m] is closed, that is, the current bound of [Xj]
38+
* does not contain any type variables; but [Xj] is being depended on by the
39+
* bound of some other type variable). Then, for all [i] in [1 .. k], [Ui,m+1]
40+
* is obtained from [Ui,m] by replacing every covariant occurrence of [Xj] by
41+
* [Uj,m], and replacing every contravariant occurrence of [Xj] by [Null].
42+
*
43+
* 3. Otherwise, (when no dependencies exist) terminate with the result
44+
* [<U1,m ..., Uk,m>].
45+
* @description Checks that instantiate-to-bounds works as expected for class
46+
* with generic function type argument.
47+
48+
*/
49+
// SharedOptions=--enable-experiment=generic-metadata
50+
51+
typedef FUNC<T> = void Function<T1 extends T>();
52+
class A<X extends FUNC<X>> {}
53+
54+
typedef exp = void Function<T>();
55+
56+
testme(A a) {
57+
// ^
58+
// [analyzer] unspecified
59+
// [cfe] unspecified
60+
61+
A<exp> a1 = a;
62+
// ^^
63+
// [analyzer] unspecified
64+
// [cfe] unspecified
65+
}
66+
67+
main() {
68+
A();
69+
//^
70+
// [analyzer] unspecified
71+
// [cfe] unspecified
72+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
/*
2+
* Copyright (c) 2020, the Dart project authors. Please see the AUTHORS file
3+
* for details. All rights reserved. Use of this source code is governed by a
4+
* BSD-style license that can be found in the LICENSE file.
5+
*/
6+
/**
7+
* @assertion The definitions of least and greatest closure are changed in null
8+
* safe libraries to substitute [Never] in positions where previously [Null
9+
* would have been substituted, and [Object?] in positions where previously
10+
* [Object] or [dynamic] would have been substituted.
11+
* @description Check that correct type is substituted for generic
12+
* [void Function<T>()] typedef.
13+
* @note Read more about the least and greatest closure test template:
14+
* https://github.com/dart-lang/co19/issues/575#issuecomment-613542349
15+
*
16+
* $Issue 45763
17+
*
18+
19+
*/
20+
// SharedOptions=--enable-experiment=generic-metadata
21+
22+
import "../../Utils/expect.dart";
23+
24+
typedef check = void Function<T>();
25+
26+
void main() {
27+
void f(check Function<T>() g) => g();
28+
Expect.throws(() { f(<T>() => captureTypeArgument()); });
29+
Expect.equals(typeOf<void Function<T>()>(), capturedTypeArgument);
30+
}

LanguageFeatures/Instantiate-to-bound/class/static/class_typedef_l1_t03.dart

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,6 @@
5050
*
5151
5252
*/
53-
import "../../../../Utils/expect.dart";
5453

5554
typedef G<X> = X Function(X);
5655
class A<X extends G<A<X>>> {}

0 commit comments

Comments
 (0)