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:
Nate Bosch 2021-04-27 20:16:08 +00:00 committed by commit-bot@chromium.org
parent 8f2c0e9bb8
commit 71fc33e427
17 changed files with 94 additions and 33 deletions

View file

@ -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

View file

@ -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;

View file

@ -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),
]);
}
}

View file

@ -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),
]);
}
}

View file

@ -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,

View file

@ -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)];

View file

@ -19,6 +19,7 @@ enum class ExperimentalFeature {
extension_methods,
constant_update_2018,
control_flow_collections,
generic_metadata,
set_literals,
spread_collections,
triple_shift,

View file

@ -4,6 +4,8 @@
//
// VMOptions=--reify-generic-functions
// @dart=2.12
import "package:expect/expect.dart";
T foo<T>(T i) => i;

View file

@ -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.

View file

@ -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> {

View file

@ -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.

View file

@ -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.
}

View file

@ -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();
}

View file

@ -6,6 +6,8 @@
// Check that annotations cannot use type arguments, but can be raw.
// @dart=2.11
class C<T> {
const C();
}

View file

@ -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

View file

@ -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;

View file

@ -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'