Skip to content

Commit 743ea34

Browse files
committed
Issue #996: tests for Generic functions as type arguments and bounds added.
1 parent 464da11 commit 743ea34

22 files changed

+1312
-0
lines changed
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks that generic invariant function can be a type argument
33+
* and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
import "../../Utils/expect.dart";
40+
41+
T test1<T>(T i) => i;
42+
void test2<T>() {}
43+
T test3<T>() => 0 as T;
44+
void test4<T>(T i) {}
45+
46+
main() {
47+
FutureOr<T Function<T>(T)> f = test1;
48+
Expect.throws(() { f = 1 as dynamic; });
49+
Expect.throws(() { f = test2 as dynamic; });
50+
Expect.throws(() { f = test3 as dynamic; });
51+
Expect.throws(() { f = test4 as dynamic; });
52+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks that generic covariant function can be a type argument
33+
* and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
import "../../Utils/expect.dart";
40+
41+
T test1<T>(T i) => i;
42+
void test2<T>() {}
43+
T test3<T>() => 0 as T;
44+
void test4<T>(T i) {}
45+
46+
main() {
47+
FutureOr<void Function<T>()> f = test2;
48+
f = test3;
49+
50+
Expect.throws(() { f = 1 as dynamic; });
51+
Expect.throws(() { f = test1 as dynamic; });
52+
Expect.throws(() { f = test4 as dynamic; });
53+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks that generic covariant function can be a type argument
33+
* and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
import "../../Utils/expect.dart";
40+
41+
T test1<T>(T i) => i;
42+
void test2<T>() {}
43+
T test3<T>() => 0 as T;
44+
void test4<T>(T i) {}
45+
46+
main() {
47+
FutureOr<T Function<T>()> f = test3;
48+
Expect.throws(() { f = 1 as dynamic; });
49+
Expect.throws(() { f = test1 as dynamic; });
50+
Expect.throws(() { f = test2 as dynamic; });
51+
Expect.throws(() { f = test4 as dynamic; });
52+
}
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks that generic invariant function can be a type argument
33+
* and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
import "../../Utils/expect.dart";
40+
41+
T test1<T>(T i) => i;
42+
void test2<T>() {}
43+
T test3<T>() => 0 as T;
44+
void test4<T>(T i) {}
45+
46+
main() {
47+
FutureOr<void Function<T>(T)> f = test4;
48+
f = test1;
49+
Expect.throws(() { f = 1 as dynamic; });
50+
Expect.throws(() { f = test2 as dynamic; });
51+
Expect.throws(() { f = test3 as dynamic; });
52+
}
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks statically that generic invariant function can be a type
33+
* argument and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
40+
T test1<T>(T i) => i;
41+
void test2<T>() {}
42+
T test3<T>() => 0 as T;
43+
void test4<T>(T i) {}
44+
45+
main() {
46+
FutureOr<T Function<T>(T)> f1 = test1;
47+
48+
FutureOr<T Function<T>(T)> f2 = 1;
49+
// ^
50+
// [analyzer] unspecified
51+
// [cfe] unspecified
52+
53+
FutureOr<T Function<T>(T)> f3 = test2;
54+
// ^
55+
// [analyzer] unspecified
56+
// [cfe] unspecified
57+
58+
FutureOr<T Function<T>(T)> f4 = test3;
59+
// ^
60+
// [analyzer] unspecified
61+
// [cfe] unspecified
62+
63+
FutureOr<T Function<T>(T)> f5 = test4;
64+
// ^
65+
// [analyzer] unspecified
66+
// [cfe] unspecified
67+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
/*
2+
* Copyright (c) 2021, 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 Allow generic function types as type arguments and bounds
8+
*
9+
* The language disallows generic function types as type arguments and bounds.
10+
*
11+
* late List<T Function<T>(T)> idFunctions; // INVALID.
12+
* var callback = [foo<T>(T value) => value]; // Inferred as above, then invalid.
13+
* late S Function<S extends T Function<T>(T)>(S) f; // INVALID.
14+
*
15+
* We remove that restriction, so a type argument and a bound can be a generic
16+
* function type.
17+
*
18+
* This requires no new syntax, and in some cases only the removal of a single
19+
* check. There might be some platforms where the implementation currently
20+
* assumes that generic function types cannot occur as the value of type
21+
* variables (an proof-of-concept attempt hit an assert in the VM). Such
22+
* assumptions will need to be flushed out with tests and fixed.
23+
*
24+
* Because we already infer List<T Function<T>(T)> in the code above, this
25+
* change will not affect type inference, it will just make the inferred type
26+
* not be an error afterwards.
27+
*
28+
* We do not expect the removal of this restriction to affect the feasibility of
29+
* type inference. After all, it's already possible to have a generic function
30+
* type occurring covariantly in a type argument, like List<T Function<T>(T)
31+
* Function()>.
32+
* @description Checks statically that generic covariant function can be a type
33+
* argument and bound of FutureOr.
34+
35+
*/
36+
//--enable-experiment=generic-metadata
37+
38+
import "dart:async";
39+
40+
T test1<T>(T i) => i;
41+
void test2<T>() {}
42+
T test3<T>() => 0 as T;
43+
void test4<T>(T i) {}
44+
45+
main() {
46+
FutureOr<void Function<T>()> f1 = test2;
47+
FutureOr<void Function<T>()> f2 = test3;
48+
49+
FutureOr<void Function<T>()> f3 = 1;
50+
// ^
51+
// [analyzer] unspecified
52+
// [cfe] unspecified
53+
54+
FutureOr<void Function<T>()> f4 = test1;
55+
// ^
56+
// [analyzer] unspecified
57+
// [cfe] unspecified
58+
59+
FutureOr<void Function<T>()> f5 = test4;
60+
// ^
61+
// [analyzer] unspecified
62+
// [cfe] unspecified
63+
}

0 commit comments

Comments
 (0)