Variance. Report errors on INOUT and OUT built-in identifiers when Feature.variance is enabled.
Change-Id: I4788439bea71532d2c52b715543f7deaeacdf519 Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/489982 Reviewed-by: Paul Berry <paulberry@google.com> Commit-Queue: Konstantin Shcheglov <scheglov@google.com> Reviewed-by: Johnni Winther <johnniwinther@google.com>
This commit is contained in:
committed by
Commit Queue
parent
99290f0c1d
commit
5ef56befcb
@@ -2504,6 +2504,15 @@ class ErrorVerifier extends RecursiveAstVisitor<void>
|
||||
diagnosticReporter.report(
|
||||
code.withArguments(name: token.lexeme).at(token),
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (_featureSet.isEnabled(Feature.variance)) {
|
||||
if (token.keyword == Keyword.INOUT || token.keyword == Keyword.OUT) {
|
||||
diagnosticReporter.report(
|
||||
code.withArguments(name: token.lexeme).at(token),
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -32,4 +32,36 @@ extension Function on Object {}
|
||||
[error(diag.builtInIdentifierAsExtensionName, 10, 8)],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension inout on Object {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsExtensionName, 10, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
extension inout on Object {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension out on Object {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsExtensionName, 10, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
extension out on Object {}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
+32
@@ -33,4 +33,36 @@ extension type Function(int it) {}
|
||||
[error(diag.builtInIdentifierAsExtensionTypeName, 15, 8)],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension type inout(int it) {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsExtensionTypeName, 15, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
extension type inout(int it) {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension type out(int it) {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsExtensionTypeName, 15, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
extension type out(int it) {}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -38,4 +38,48 @@ import 'dart:async' as Function;
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
import 'dart:async' as inout;
|
||||
''',
|
||||
[
|
||||
error(diag.unusedImport, 7, 12),
|
||||
error(diag.builtInIdentifierAsPrefixName, 23, 5),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
test_inout_language310() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
// @dart = 3.10
|
||||
import 'dart:async' as inout;
|
||||
''',
|
||||
[error(diag.unusedImport, 23, 12)],
|
||||
);
|
||||
}
|
||||
|
||||
test_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
import 'dart:async' as out;
|
||||
''',
|
||||
[
|
||||
error(diag.unusedImport, 7, 12),
|
||||
error(diag.builtInIdentifierAsPrefixName, 23, 3),
|
||||
],
|
||||
);
|
||||
}
|
||||
|
||||
test_out_language310() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
// @dart = 3.10
|
||||
import 'dart:async' as out;
|
||||
''',
|
||||
[error(diag.unusedImport, 23, 12)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -33,7 +33,39 @@ class Function {}
|
||||
);
|
||||
}
|
||||
|
||||
test_enum() async {
|
||||
test_class_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class inout {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 6, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class inout {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class out {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 6, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class out {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_enum_as() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
enum as {
|
||||
@@ -44,6 +76,38 @@ enum as {
|
||||
);
|
||||
}
|
||||
|
||||
test_enum_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
enum inout {v}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 5, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_enum_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
enum inout {v}
|
||||
''');
|
||||
}
|
||||
|
||||
test_enum_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
enum out {v}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 5, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_enum_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
enum out {v}
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_as() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
@@ -62,6 +126,22 @@ mixin Function {}
|
||||
);
|
||||
}
|
||||
|
||||
test_mixin_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
mixin inout {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 6, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_mixin_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
mixin inout {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_OK_on() async {
|
||||
await assertNoErrorsInCode(r'''
|
||||
class A {}
|
||||
@@ -75,6 +155,22 @@ mixin M2 implements on {}
|
||||
class B = A with on;
|
||||
class C = B with M;
|
||||
class D = Object with M2;
|
||||
''');
|
||||
}
|
||||
|
||||
test_mixin_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
mixin out {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeName, 6, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_mixin_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
mixin out {}
|
||||
''');
|
||||
}
|
||||
}
|
||||
|
||||
+68
@@ -34,6 +34,38 @@ class A<Function> {}
|
||||
);
|
||||
}
|
||||
|
||||
test_class_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class A<inout> {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 8, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class A<inout> {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_class_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class A<out> {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 8, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_class_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class A<out> {}
|
||||
''');
|
||||
}
|
||||
|
||||
test_extension_as() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
@@ -43,6 +75,24 @@ extension <as> on List {}
|
||||
);
|
||||
}
|
||||
|
||||
test_extension_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension <inout> on List {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 11, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_extension_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
extension <out> on List {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 11, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_function_as() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
@@ -51,4 +101,22 @@ void f<as>() {}
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 7, 2)],
|
||||
);
|
||||
}
|
||||
|
||||
test_function_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
void f<inout>() {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 7, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_function_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
void f<out>() {}
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypeParameterName, 7, 3)],
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -26,6 +26,46 @@ class as = A with B;
|
||||
);
|
||||
}
|
||||
|
||||
test_classTypeAlias_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class A {}
|
||||
mixin B {}
|
||||
class inout = A with B;
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 28, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_classTypeAlias_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class A {}
|
||||
mixin B {}
|
||||
class inout = A with B;
|
||||
''');
|
||||
}
|
||||
|
||||
test_classTypeAlias_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
class A {}
|
||||
mixin B {}
|
||||
class out = A with B;
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 28, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_classTypeAlias_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
class A {}
|
||||
mixin B {}
|
||||
class out = A with B;
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_classic() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
@@ -50,6 +90,38 @@ typedef void as();
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_classic_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
typedef void inout();
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 13, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_classic_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
typedef void inout();
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_classic_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
typedef void out();
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 13, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_classic_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
typedef void out();
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_generic_as() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
@@ -62,6 +134,38 @@ typedef as = void Function();
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_generic_inout() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
typedef inout = void Function();
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 8, 5)],
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_generic_inout_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
typedef inout = void Function();
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_generic_out() async {
|
||||
await assertErrorsInCode(
|
||||
'''
|
||||
typedef out = void Function();
|
||||
''',
|
||||
[error(diag.builtInIdentifierAsTypedefName, 8, 3)],
|
||||
);
|
||||
}
|
||||
|
||||
test_typedef_generic_out_language310() async {
|
||||
await assertNoErrorsInCode('''
|
||||
// @dart = 3.10
|
||||
typedef out = void Function();
|
||||
''');
|
||||
}
|
||||
|
||||
test_typedef_interfaceType_as() async {
|
||||
await assertErrorsInCode(
|
||||
r'''
|
||||
|
||||
@@ -2,8 +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.
|
||||
|
||||
// `out` and `inout` are built-in identifiers. They cannot be used as type
|
||||
// names.
|
||||
// `out` and `inout` are built-in identifiers.They cannot be used as names in
|
||||
// declarations.
|
||||
|
||||
// SharedOptions=--enable-experiment=variance
|
||||
|
||||
@@ -18,35 +18,45 @@ class B<inout> {}
|
||||
// [cfe] unspecified
|
||||
|
||||
class C<out, inout> {}
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
F<inout, out>() {}
|
||||
//^
|
||||
// [analyzer] unspecified
|
||||
//^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
mixin G<out, inout> {}
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
class I<out out> {}
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
class J<out inout> {}
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
typedef H<inout, out> = out Function(inout);
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// [cfe] unspecified
|
||||
|
||||
class out {}
|
||||
@@ -55,7 +65,6 @@ class out {}
|
||||
// [cfe] unspecified
|
||||
|
||||
class inout {}
|
||||
|
||||
// ^
|
||||
// [analyzer] unspecified
|
||||
// [cfe] unspecified
|
||||
|
||||
@@ -27,10 +27,6 @@ mixin E<in T extends E1> {}
|
||||
|
||||
class F<out T> = Object with D<T>;
|
||||
|
||||
class G<out out> {}
|
||||
|
||||
class H<out inout> {}
|
||||
|
||||
main() {
|
||||
B<int, String, bool> b = B();
|
||||
|
||||
@@ -38,8 +34,4 @@ main() {
|
||||
Expect.equals(2, c.foo(3));
|
||||
|
||||
F<int> f = F();
|
||||
|
||||
G<int> g = G();
|
||||
|
||||
H<int> h = H();
|
||||
}
|
||||
|
||||
@@ -60,6 +60,8 @@ class D<in out inout in out X> {}
|
||||
// [cfe] Each type parameter can have at most one variance modifier.
|
||||
|
||||
typedef E<out T> = T Function(T a);
|
||||
// ^^^
|
||||
// [analyzer] COMPILE_TIME_ERROR.BUILT_IN_IDENTIFIER_IN_DECLARATION
|
||||
// ^
|
||||
// [analyzer] SYNTACTIC_ERROR.EXPECTED_TOKEN
|
||||
// [cfe] Expected ',' before this.
|
||||
|
||||
Reference in New Issue
Block a user