mirror of
https://github.com/dart-lang/sdk
synced 2024-10-02 23:59:16 +00:00
Enable experiment generic_metadata
Change-Id: Iff050e6a2a1c0c2b8baca211a523f9dd77cfbd4a TEST=Existing tests for the feature. Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/193748 Reviewed-by: Leaf Petersen <leafp@google.com> Reviewed-by: Nate Bosch <nbosch@google.com> Commit-Queue: Leaf Petersen <leafp@google.com>
This commit is contained in:
parent
8f2c0e9bb8
commit
71fc33e427
38
CHANGELOG.md
38
CHANGELOG.md
|
@ -54,6 +54,44 @@ Updated the Linter to `1.3.0`, which includes:
|
|||
as an unsigned integer, so `a >>> b` gives the same result as
|
||||
`a.toUnsigned(32) >>> b` on the VM.
|
||||
|
||||
* Prior to Dart 2.14, metadata (annotations) were not permitted to be
|
||||
specified with generic type arguments. This restriction is lifted in Dart
|
||||
Dart 2.14.
|
||||
|
||||
```dart
|
||||
class C<T> {
|
||||
const C();
|
||||
}
|
||||
@C(); // Previously permitted.
|
||||
@C<int>(); // Previously an error, now permitted.
|
||||
```
|
||||
|
||||
* Prior to Dart 2.14, generic function types were not permitted as arguments
|
||||
to generic classes or functions, nor to be used as generic bounds. This
|
||||
restriction is lifted in Dart 2.14.
|
||||
|
||||
```dart
|
||||
T wrapWithLogging<T>(T f) {
|
||||
if (f is void Function<T>(T x)) {
|
||||
return <S>(S x) {
|
||||
print("Call: f<$S>($x)");
|
||||
var r = f<S>(x);
|
||||
print("Return: $x");
|
||||
return r;
|
||||
} as T;
|
||||
} // More cases here
|
||||
return f;
|
||||
}
|
||||
void foo<T>(T x) {
|
||||
print("Foo!");
|
||||
}
|
||||
void main() {
|
||||
// Previously an error, now permitted.
|
||||
var f = wrapWithLogging<void Function<T>(T)>(foo);
|
||||
f<int>(3);
|
||||
}
|
||||
```
|
||||
|
||||
## 2.13.0
|
||||
|
||||
### Language
|
||||
|
|
|
@ -130,9 +130,9 @@ class ExperimentalFeatures {
|
|||
isEnabledByDefault: IsEnabledByDefault.generic_metadata,
|
||||
isExpired: IsExpired.generic_metadata,
|
||||
documentation:
|
||||
'Allow annotations to accept type arguments; also allow generic function types as type arguments',
|
||||
'Allow annotations to accept type arguments; also allow generic function types as type arguments.',
|
||||
experimentalReleaseVersion: null,
|
||||
releaseVersion: null,
|
||||
releaseVersion: Version.parse('2.14.0'),
|
||||
);
|
||||
|
||||
static final non_nullable = ExperimentalFeature(
|
||||
|
@ -225,7 +225,7 @@ class IsEnabledByDefault {
|
|||
static const bool extension_types = false;
|
||||
|
||||
/// Default state of the experiment "generic-metadata"
|
||||
static const bool generic_metadata = false;
|
||||
static const bool generic_metadata = true;
|
||||
|
||||
/// Default state of the experiment "non-nullable"
|
||||
static const bool non_nullable = true;
|
||||
|
|
|
@ -194,6 +194,7 @@ class GenericTypeAliasDriverResolutionWithoutGenericMetadataTest
|
|||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_def_class() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
class C<T> {}
|
||||
|
||||
typedef G = Function<S>();
|
||||
|
@ -201,23 +202,25 @@ typedef G = Function<S>();
|
|||
C<G>? x;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
45, 1),
|
||||
59, 1),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_literal_class() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
class C<T> {}
|
||||
|
||||
C<Function<S>()>? x;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
17, 13),
|
||||
31, 13),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_literal_function() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
void f<T>(T) {}
|
||||
|
||||
main() {
|
||||
|
@ -225,12 +228,13 @@ main() {
|
|||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
30, 13),
|
||||
44, 13),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_literal_functionType() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
late T Function<T>(T?) f;
|
||||
|
||||
main() {
|
||||
|
@ -238,12 +242,13 @@ main() {
|
|||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
40, 13),
|
||||
54, 13),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_literal_method() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
class C {
|
||||
void f<T>(T) {}
|
||||
}
|
||||
|
@ -253,18 +258,19 @@ main() {
|
|||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
52, 13),
|
||||
66, 13),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypeCannotBeTypeArgument_literal_typedef() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
typedef T F<T>(T t);
|
||||
|
||||
F<Function<S>()>? x;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_TYPE_ARGUMENT,
|
||||
24, 13),
|
||||
38, 13),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -72,26 +72,29 @@ class GenericFunctionTypeCannotBeBoundWithoutGenericMetadataTest
|
|||
|
||||
test_class() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
class C<T extends S Function<S>(S)> {
|
||||
}
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 18, 16),
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 32, 16),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunction() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
late T Function<T extends S Function<S>(S)>(T) fun;
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 26, 16),
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 40, 16),
|
||||
]);
|
||||
}
|
||||
|
||||
test_genericFunctionTypedef() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
typedef foo = T Function<T extends S Function<S>(S)>(T t);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 35, 16),
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 49, 16),
|
||||
]);
|
||||
}
|
||||
|
||||
|
@ -103,9 +106,10 @@ class C<T extends void Function(S Function<S>(S))> {}
|
|||
|
||||
test_typedef() async {
|
||||
await assertErrorsInCode(r'''
|
||||
// @dart=2.12
|
||||
typedef T foo<T extends S Function<S>(S)>(T t);
|
||||
''', [
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 24, 16),
|
||||
error(CompileTimeErrorCode.GENERIC_FUNCTION_TYPE_CANNOT_BE_BOUND, 38, 16),
|
||||
]);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -83,7 +83,7 @@ const Map<ExperimentalFlag, bool> defaultExperimentalFlags = {
|
|||
ExperimentalFlag.controlFlowCollections: true,
|
||||
ExperimentalFlag.extensionMethods: true,
|
||||
ExperimentalFlag.extensionTypes: false,
|
||||
ExperimentalFlag.genericMetadata: false,
|
||||
ExperimentalFlag.genericMetadata: true,
|
||||
ExperimentalFlag.nonNullable: true,
|
||||
ExperimentalFlag.nonfunctionTypeAliases: true,
|
||||
ExperimentalFlag.setLiterals: true,
|
||||
|
|
|
@ -18,7 +18,7 @@ namespace dart {
|
|||
|
||||
bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
|
||||
constexpr bool kFeatureValues[] = {
|
||||
true, true, true, true, true, true, true, true,
|
||||
true, true, true, true, true, true, true, true, true,
|
||||
};
|
||||
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureValues));
|
||||
return kFeatureValues[static_cast<int>(feature)];
|
||||
|
@ -26,10 +26,15 @@ bool GetExperimentalFeatureDefault(ExperimentalFeature feature) {
|
|||
|
||||
const char* GetExperimentalFeatureName(ExperimentalFeature feature) {
|
||||
constexpr const char* kFeatureNames[] = {
|
||||
"nonfunction-type-aliases", "non-nullable",
|
||||
"extension-methods", "constant-update-2018",
|
||||
"control-flow-collections", "set-literals",
|
||||
"spread-collections", "triple-shift",
|
||||
"nonfunction-type-aliases",
|
||||
"non-nullable",
|
||||
"extension-methods",
|
||||
"constant-update-2018",
|
||||
"control-flow-collections",
|
||||
"generic-metadata",
|
||||
"set-literals",
|
||||
"spread-collections",
|
||||
"triple-shift",
|
||||
};
|
||||
ASSERT(static_cast<size_t>(feature) < ARRAY_SIZE(kFeatureNames));
|
||||
return kFeatureNames[static_cast<int>(feature)];
|
||||
|
|
|
@ -19,6 +19,7 @@ enum class ExperimentalFeature {
|
|||
extension_methods,
|
||||
constant_update_2018,
|
||||
control_flow_collections,
|
||||
generic_metadata,
|
||||
set_literals,
|
||||
spread_collections,
|
||||
triple_shift,
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
//
|
||||
// VMOptions=--reify-generic-functions
|
||||
|
||||
// @dart=2.12
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
T foo<T>(T i) => i;
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// 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.
|
||||
|
||||
// @dart=2.12
|
||||
|
||||
// Check that annotations inside function bodies cannot use type arguments, but
|
||||
// can be raw.
|
||||
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// 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.
|
||||
|
||||
// @dart=2.12
|
||||
|
||||
// Check that annotations cannot use type arguments, but can be raw.
|
||||
|
||||
class C<T> {
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
// 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.
|
||||
|
||||
// @dart=2.12
|
||||
|
||||
// Verify that function type parameter S can be resolved in bar's result type.
|
||||
// Verify that generic function types are not allowed as type arguments.
|
||||
|
||||
|
|
|
@ -1,11 +1,9 @@
|
|||
class Hest<TypeX extends Fisk> {}
|
||||
// ^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.NOT_INSTANTIATED_BOUND
|
||||
// ^
|
||||
// [cfe] Type variables can't have generic function types in their bounds.
|
||||
|
||||
typedef Fisk = void Function // don't merge lines
|
||||
// [error line 7, column 1, length 346]
|
||||
// [error line 5, column 1, length 346]
|
||||
// [analyzer] COMPILE_TIME_ERROR.TYPE_ALIAS_CANNOT_REFERENCE_ITSELF
|
||||
// ^
|
||||
// [cfe] Generic type 'Fisk' can't be used without type arguments in the bounds of its own type variables. It is referenced indirectly through 'Hest'.
|
||||
|
@ -15,6 +13,4 @@ typedef Fisk = void Function // don't merge lines
|
|||
|
||||
main() {
|
||||
Hest hest = new Hest();
|
||||
// ^
|
||||
// [cfe] Generic function type 'void Function<TypeY>()' inferred as a type argument.
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
// Check that annotations inside function bodies cannot use type arguments, but
|
||||
// can be raw.
|
||||
|
||||
// @dart=2.11
|
||||
|
||||
class C<T> {
|
||||
const C();
|
||||
}
|
||||
|
|
|
@ -6,6 +6,8 @@
|
|||
|
||||
// Check that annotations cannot use type arguments, but can be raw.
|
||||
|
||||
// @dart=2.11
|
||||
|
||||
class C<T> {
|
||||
const C();
|
||||
}
|
||||
|
|
|
@ -7,6 +7,8 @@
|
|||
// Verify that function type parameter S can be resolved in bar's result type.
|
||||
// Verify that generic function types are not allowed as type arguments.
|
||||
|
||||
// @dart=2.11
|
||||
|
||||
import "package:expect/expect.dart";
|
||||
|
||||
int foo
|
||||
|
|
|
@ -47,11 +47,6 @@ class G {
|
|||
G.named(this.field);
|
||||
}
|
||||
|
||||
@H<int>() // //# 05: compile-time error
|
||||
class H<T> {
|
||||
const H();
|
||||
}
|
||||
|
||||
@I[0] // //# 06: compile-time error
|
||||
class I {}
|
||||
|
||||
|
@ -187,7 +182,6 @@ main() {
|
|||
reflectClass(E).metadata;
|
||||
reflectClass(F).metadata;
|
||||
reflectClass(G).metadata;
|
||||
reflectClass(H).metadata;
|
||||
reflectClass(I).metadata;
|
||||
reflectClass(J).metadata;
|
||||
reflectClass(K).metadata;
|
||||
|
|
|
@ -116,9 +116,6 @@ features:
|
|||
value-class:
|
||||
help: "Value class"
|
||||
|
||||
generic-metadata:
|
||||
help: "Allow annotations to accept type arguments; also allow generic function types as type arguments"
|
||||
|
||||
extension-types:
|
||||
help: "Extension Types"
|
||||
|
||||
|
@ -164,6 +161,12 @@ features:
|
|||
enabledIn: '2.0.0'
|
||||
expired: true
|
||||
|
||||
generic-metadata:
|
||||
help: >-
|
||||
Allow annotations to accept type arguments;
|
||||
also allow generic function types as type arguments.
|
||||
enabledIn: '2.14.0'
|
||||
|
||||
set-literals:
|
||||
help: "Set Literals"
|
||||
enabledIn: '2.0.0'
|
||||
|
|
Loading…
Reference in a new issue