Report error for `extends void` type parameters

Change-Id: I634b836ea40199a1e7962b7d07ca9f5d1ef3f16a
Reviewed-on: https://dart-review.googlesource.com/74680
Reviewed-by: Brian Wilkerson <brianwilkerson@google.com>
Commit-Queue: Dan Rubel <danrubel@google.com>
diff --git a/pkg/analyzer/lib/src/fasta/ast_builder.dart b/pkg/analyzer/lib/src/fasta/ast_builder.dart
index 9d0b2d1..3b43199 100644
--- a/pkg/analyzer/lib/src/fasta/ast_builder.dart
+++ b/pkg/analyzer/lib/src/fasta/ast_builder.dart
@@ -46,8 +46,7 @@
         messageStaticConstructor,
         messageTypedefNotFunction,
         templateDuplicateLabelInSwitchStatement,
-        templateExpectedIdentifier,
-        templateExpectedType;
+        templateExpectedIdentifier;
 import 'package:front_end/src/fasta/quote.dart';
 import 'package:front_end/src/fasta/scanner/token_constants.dart';
 import 'package:front_end/src/fasta/source/stack_listener.dart'
@@ -950,17 +949,6 @@
     debugEvent("AsOperator");
 
     TypeAnnotation type = pop();
-    if (type is TypeName) {
-      Identifier name = type.name;
-      if (name is SimpleIdentifier) {
-        if (name.name == 'void') {
-          Token token = name.beginToken;
-          // TODO(danrubel): This needs to be reported during fasta resolution.
-          handleRecoverableError(
-              templateExpectedType.withArguments(token), token, token);
-        }
-      }
-    }
     Expression expression = pop();
     push(ast.asExpression(expression, asOperator, type));
   }
@@ -993,17 +981,6 @@
     debugEvent("IsOperator");
 
     TypeAnnotation type = pop();
-    if (type is TypeName) {
-      Identifier name = type.name;
-      if (name is SimpleIdentifier) {
-        if (name.name == 'void') {
-          Token token = name.beginToken;
-          // TODO(danrubel): This needs to be reported during fasta resolution.
-          handleRecoverableError(
-              templateExpectedType.withArguments(token), token, token);
-        }
-      }
-    }
     Expression expression = pop();
     push(ast.isExpression(expression, isOperator, not, type));
   }
diff --git a/pkg/analyzer/test/generated/parser_test.dart b/pkg/analyzer/test/generated/parser_test.dart
index dc34a9e..070694e 100644
--- a/pkg/analyzer/test/generated/parser_test.dart
+++ b/pkg/analyzer/test/generated/parser_test.dart
@@ -16205,6 +16205,20 @@
     _assertIsDeclarationName(declaration.typeParameters.typeParameters[0].name);
   }
 
+  void test_parseClassDeclaration_typeParameters_extends_void() {
+    parseCompilationUnit('class C<T extends void>{}',
+        errors: usingFastaParser
+            ? [expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 18, 4)]
+            : [
+                expectedError(ParserErrorCode.EXPECTED_TYPE_NAME, 18, 4),
+                expectedError(ParserErrorCode.EXPECTED_TOKEN, 18, 4),
+                expectedError(ParserErrorCode.MISSING_CLASS_BODY, 18, 4),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 22, 1),
+                expectedError(ParserErrorCode.EXPECTED_EXECUTABLE, 22, 1),
+                expectedError(ParserErrorCode.UNEXPECTED_TOKEN, 22, 1),
+              ]);
+  }
+
   void test_parseClassDeclaration_withDocumentationComment() {
     createParser('/// Doc\nclass C {}');
     var classDeclaration = parseFullCompilationUnitMember() as ClassDeclaration;
diff --git a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
index 489cfba..f0bbf845 100644
--- a/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
+++ b/pkg/analyzer/test/src/dart/resolution/mixin_test.dart
@@ -1,4 +1,5 @@
 import 'package:analyzer/dart/element/element.dart';
+import 'package:analyzer/src/dart/error/syntactic_errors.dart';
 import 'package:analyzer/src/error/codes.dart';
 import 'package:test/test.dart';
 import 'package:test_reflective_loader/test_reflective_loader.dart';
@@ -800,6 +801,7 @@
 
     assertTestErrors([
       CompileTimeErrorCode.IMPLEMENTS_NON_CLASS,
+      ParserErrorCode.EXPECTED_TYPE_NAME,
     ]);
 
     var element = findElement.mixin('M');
@@ -1162,6 +1164,7 @@
 
     assertTestErrors([
       CompileTimeErrorCode.MIXIN_SUPER_CLASS_CONSTRAINT_NON_INTERFACE,
+      ParserErrorCode.EXPECTED_TYPE_NAME,
     ]);
 
     var element = findElement.mixin('M');
diff --git a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
index b8458bf..e373365 100644
--- a/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
+++ b/pkg/front_end/lib/src/fasta/fasta_codes_generated.dart
@@ -4732,7 +4732,7 @@
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const MessageCode messageInvalidVoid = const MessageCode("InvalidVoid",
-    analyzerCode: "INVALID_USE_OF_VOID",
+    analyzerCode: "EXPECTED_TYPE_NAME",
     message:
         r"""Type 'void' can't be used here because it isn't a return type.""",
     tip:
diff --git a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
index 6bfbc3c..84d4024 100644
--- a/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
+++ b/pkg/front_end/lib/src/fasta/parser/type_info_impl.dart
@@ -842,7 +842,7 @@
       if (typeInfo != null) {
         assert(optional('extends', next2));
         extendsOrSuper = next2;
-        token2 = typeInfo.ensureTypeOrVoid(next2, parser);
+        token2 = typeInfo.ensureTypeNotVoid(next2, parser);
         next2 = token2.next;
       } else {
         assert(!optional('extends', next2));
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 94e2ef2..2823171 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -816,7 +816,7 @@
 InvalidVoid:
   template: "Type 'void' can't be used here because it isn't a return type."
   tip: "Try removing 'void' keyword or replace it with 'var', 'final', or a type."
-  analyzerCode: INVALID_USE_OF_VOID
+  analyzerCode: EXPECTED_TYPE_NAME
   script:
     - "void x; main() {}"
     - "foo(void x) {} main() { foo(null); }"
diff --git a/pkg/front_end/test/fasta/parser/type_info_test.dart b/pkg/front_end/test/fasta/parser/type_info_test.dart
index 89f15e6..90db70b 100644
--- a/pkg/front_end/test/fasta/parser/type_info_test.dart
+++ b/pkg/front_end/test/fasta/parser/type_info_test.dart
@@ -1504,6 +1504,24 @@
     ]);
   }
 
+  void test_computeTypeParam_complex_extends_void() {
+    expectComplexTypeParam('<T extends void>', expectedErrors: [
+      error(codeInvalidVoid, 11, 4),
+    ], expectedCalls: [
+      'beginTypeVariables <',
+      'beginMetadataStar T',
+      'endMetadataStar 0',
+      'handleIdentifier T typeVariableDeclaration',
+      'beginTypeVariable T',
+      'handleTypeVariablesDefined void 1',
+      'handleIdentifier void typeReference',
+      'handleNoTypeArguments >',
+      'handleType void',
+      'endTypeVariable > 0 extends',
+      'endTypeVariables < >'
+    ]);
+  }
+
   void test_computeTypeParam_complex_recovery() {
     expectComplexTypeParam('<S Function()>', expectedErrors: [
       error(codeUnexpectedToken, 3, 8),
diff --git a/tests/co19/co19-kernel.status b/tests/co19/co19-kernel.status
index ffcc6e2..456721c 100644
--- a/tests/co19/co19-kernel.status
+++ b/tests/co19/co19-kernel.status
@@ -14,7 +14,6 @@
 Language/Types/Parameterized_Types/arity_mismatch_t01: CompileTimeError
 Language/Types/Parameterized_Types/arity_mismatch_t05: CompileTimeError
 Language/Types/Parameterized_Types/arity_mismatch_t07: CompileTimeError
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
 LayoutTests/*: Skip # TODO(ahe): Make dart:html available.
 LibTest/collection/Maps/*: Skip # Maps class no longer exists.
@@ -1117,7 +1116,6 @@
 Language/Types/Type_Void/returning_t03: CompileTimeError
 Language/Types/Type_Void/returning_t04: CompileTimeError
 Language/Types/Type_Void/returning_t05: CompileTimeError
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: MissingCompileTimeError
 Language/Types/Type_Void/syntax_t09: Pass
 Language/Types/Type_Void/using_t01: CompileTimeError
diff --git a/tests/co19_2/co19_2-analyzer.status b/tests/co19_2/co19_2-analyzer.status
index 56a4a12..8eaefac 100644
--- a/tests/co19_2/co19_2-analyzer.status
+++ b/tests/co19_2/co19_2-analyzer.status
@@ -128,7 +128,6 @@
 Language/Statements/Return/no_expression_function_t16: CompileTimeError # issue #34319
 Language/Statements/Return/no_expression_not_function_t01: CompileTimeError # issue #34319
 Language/Types/Interface_Types/subtype_t30: CompileTimeError # Please triage this failure
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError # Issue 33995
 Language/Types/Type_Void/syntax_t09: CompileTimeError # Please triage this failure
 Language/Types/Type_Void/using_t02: CompileTimeError # Please triage this failure
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_named_extends_neg_assign_l1_t03: MissingCompileTimeError # Issue 34087
@@ -180,7 +179,6 @@
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t05: Crash # Issue 33152, 33477
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t06: Crash # Issue 33152, 33477
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_assign_l4_t07: Crash # Issue 33152, 33477
-LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t04: MissingCompileTimeError # Issue 33995--use-fasta-parser
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t10: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_pos_l1_t04: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_pos_l1_t05: CompileTimeError # Issue 33995
@@ -195,7 +193,6 @@
 LanguageFeatures/Instantiate-to-bound/function/function_pos_l1_t01: CompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t19: CompileTimeError # Issue 33995
-LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t01: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t02: MissingCompileTimeError # Issue 33308
 LanguageFeatures/Instantiate-to-bound/mixin/mixin_neg_l1_t02: MissingCompileTimeError # Issue 33596
@@ -206,11 +203,9 @@
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l1_t03: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t02: Crash # Issue 33599
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t03: MissingCompileTimeError # Issue 33995--use-fasta-parser
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t04: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t02: Crash # Issue 33599
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t03: MissingCompileTimeError # Issue 33995
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t04: MissingCompileTimeError # Issue 33597
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l2_t01: Crash # Issue 33599
 LanguageFeatures/Super-bounded-types/motivation_example_A01_t01: CompileTimeError # Issue 32903
diff --git a/tests/co19_2/co19_2-kernel.status b/tests/co19_2/co19_2-kernel.status
index ac12d1b..fdd22f1 100644
--- a/tests/co19_2/co19_2-kernel.status
+++ b/tests/co19_2/co19_2-kernel.status
@@ -151,7 +151,6 @@
 Language/Types/Static_Types/malformed_type_t01/04: MissingCompileTimeError # Issue 33308
 Language/Types/Static_Types/malformed_type_t01/05: MissingCompileTimeError # Issue 33308
 Language/Types/Static_Types/malformed_type_t01/06: MissingCompileTimeError # Issue 33308
-Language/Types/Type_Void/syntax_t08: MissingCompileTimeError # Issue 33308
 Language/Types/Type_Void/syntax_t09: CompileTimeError # Test contains a compile-time error
 Language/Types/Type_Void/using_t02: CompileTimeError # Test contains a compile-time error
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_named_extends_neg_assign_l1_t01: MissingCompileTimeError # Please triage this failure
@@ -206,7 +205,6 @@
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t19: MissingCompileTimeError # Issue 34087
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t20: MissingCompileTimeError # Issue 34087
 LanguageFeatures/Instantiate-to-bound/Callable/Callable_ret_extends_neg_assign_l1_t21: MissingCompileTimeError # Issue 34087
-LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/class/custom_extends_neg_l1_t05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_named_extends_neg_assign_l1_t03: MissingCompileTimeError
@@ -251,7 +249,6 @@
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t18: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t20: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_assign_l1_t21: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/function/function_ret_extends_neg_l1_t02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t01: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/interface/interface_neg_assign_l2_t02: MissingCompileTimeError
@@ -264,10 +261,8 @@
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_named_extends_neg_l2_t02: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_optparam_extends_neg_l2_t02: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_param_extends_neg_l2_t02: MissingCompileTimeError
-LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t03: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t04: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l1_t05: MissingCompileTimeError
 LanguageFeatures/Instantiate-to-bound/typedef/typedef_ret_extends_neg_l2_t02: MissingCompileTimeError