Reland "[vm/ffi] Disallow empty `Struct`s"

Closes: https://github.com/dart-lang/sdk/issues/43974

TEST=tests/ffi/vmspecific_static_checks_test.dart

Change-Id: I35e6f5315826a751e5ce017a6a618c2c224c0f84
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/180189
Commit-Queue: Daco Harkes <dacoharkes@google.com>
Reviewed-by: Aske Simon Christensen <askesc@google.com>
diff --git a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
index 5ba8d5f..b372ad4 100644
--- a/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
+++ b/pkg/_fe_analyzer_shared/lib/src/messages/codes_generated.dart
@@ -3767,32 +3767,6 @@
 }
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Template<
-    Message Function(
-        String
-            name)> templateFfiEmptyStructWarning = const Template<
-        Message Function(String name)>(
-    messageTemplate:
-        r"""Struct '#name' is empty. Support for empty structs is deprecated and will be removed in the next stable version of Dart. Use Opaque instead.""",
-    withArguments: _withArgumentsFfiEmptyStructWarning);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-const Code<Message Function(String name)> codeFfiEmptyStructWarning =
-    const Code<Message Function(String name)>("FfiEmptyStructWarning",
-        analyzerCodes: <String>["EMPTY_STRUCT_WARNING"],
-        severity: Severity.info);
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
-Message _withArgumentsFfiEmptyStructWarning(String name) {
-  if (name.isEmpty) throw 'No name provided';
-  name = demangleMixinApplicationName(name);
-  return new Message(codeFfiEmptyStructWarning,
-      message:
-          """Struct '${name}' is empty. Support for empty structs is deprecated and will be removed in the next stable version of Dart. Use Opaque instead.""",
-      arguments: {'name': name});
-}
-
-// DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
 const Code<Null> codeFfiExceptionalReturnNull = messageFfiExceptionalReturnNull;
 
 // DO NOT EDIT. THIS FILE IS GENERATED. SEE TOP OF FILE.
diff --git a/pkg/analyzer/lib/error/error.dart b/pkg/analyzer/lib/error/error.dart
index 9d84c71..54cd975 100644
--- a/pkg/analyzer/lib/error/error.dart
+++ b/pkg/analyzer/lib/error/error.dart
@@ -459,7 +459,6 @@
   CompileTimeErrorCode.YIELD_OF_INVALID_TYPE,
   FfiCode.ANNOTATION_ON_POINTER_FIELD,
   FfiCode.EMPTY_STRUCT,
-  FfiCode.EMPTY_STRUCT_WARNING,
   FfiCode.EXTRA_ANNOTATION_ON_STRUCT_FIELD,
   FfiCode.EXTRA_SIZE_ANNOTATION_CARRAY,
   FfiCode.FIELD_IN_STRUCT_WITH_INITIALIZER,
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
index b44213b..1e71193 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.dart
@@ -31,17 +31,6 @@
       correction: "Try adding a field to '{0}' or use a different Struct.");
 
   /**
-   * Parameters:
-   * 0: the name of the struct class
-   */
-  static const FfiCode EMPTY_STRUCT_WARNING = FfiCode(
-      name: 'EMPTY_STRUCT_WARNING',
-      message:
-          "Struct '{0}' is empty. Support for empty structs is deprecated and will be removed in the next stable version of Dart. Use Opaque instead.",
-      correction: "Try adding a field to '{0}' or use a different Struct.",
-      type: ErrorType.HINT);
-
-  /**
    * No parameters.
    */
   static const FfiCode EXTRA_ANNOTATION_ON_STRUCT_FIELD = FfiCode(
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 9b71259..bf59990 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -67,8 +67,8 @@
         if (className == _structClassName) {
           inStruct = true;
           if (node.declaredElement!.isEmptyStruct) {
-            _errorReporter.reportErrorForNode(
-                FfiCode.EMPTY_STRUCT_WARNING, node, [node.name]);
+            _errorReporter
+                .reportErrorForNode(FfiCode.EMPTY_STRUCT, node, [node.name]);
           }
         } else if (className != _allocatorClassName &&
             className != _opaqueClassName) {
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
index e52db81..00380d1 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_struct_class_test.dart
@@ -39,7 +39,7 @@
 class S extends Struct {}
 class C implements S {}
 ''', [
-      error(FfiCode.EMPTY_STRUCT_WARNING, 19, 25),
+      error(FfiCode.EMPTY_STRUCT, 19, 25),
       error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_IMPLEMENTS, 64, 1),
     ]);
   }
@@ -53,7 +53,7 @@
 class S extends Struct {}
 class C with S {}
 ''', [
-      error(FfiCode.EMPTY_STRUCT_WARNING, 19, 25),
+      error(FfiCode.EMPTY_STRUCT, 19, 25),
       error(CompileTimeErrorCode.MIXIN_INHERITS_FROM_NOT_OBJECT, 58, 1),
       error(FfiCode.SUBTYPE_OF_STRUCT_CLASS_IN_WITH, 58, 1),
     ]);
diff --git a/pkg/front_end/lib/src/api_unstable/vm.dart b/pkg/front_end/lib/src/api_unstable/vm.dart
index 9bfeea8..78acbcf 100644
--- a/pkg/front_end/lib/src/api_unstable/vm.dart
+++ b/pkg/front_end/lib/src/api_unstable/vm.dart
@@ -55,7 +55,6 @@
         noLength,
         templateFfiDartTypeMismatch,
         templateFfiEmptyStruct,
-        templateFfiEmptyStructWarning,
         templateFfiExpectedExceptionalReturn,
         templateFfiExpectedNoExceptionalReturn,
         templateFfiExtendsOrImplementsSealedClass,
diff --git a/pkg/front_end/messages.yaml b/pkg/front_end/messages.yaml
index 44544f2..5d8cdd8 100644
--- a/pkg/front_end/messages.yaml
+++ b/pkg/front_end/messages.yaml
@@ -4249,13 +4249,6 @@
   template: "Struct '#name' is empty. Empty structs are undefined behavior."
   external: test/ffi_test.dart
 
-FfiEmptyStructWarning:
-  # Used by dart:ffi
-  template: "Struct '#name' is empty. Support for empty structs is deprecated and will be removed in the next stable version of Dart. Use Opaque instead."
-  analyzerCode: EMPTY_STRUCT_WARNING
-  severity: INFO
-  external: test/ffi_test.dart
-
 FfiTypeInvalid:
   # Used by dart:ffi
   template: "Expected type '#type' to be a valid and instantiated subtype of 'NativeType'."
diff --git a/pkg/vm/lib/transformations/ffi_definitions.dart b/pkg/vm/lib/transformations/ffi_definitions.dart
index 5c114c2..10cfe47 100644
--- a/pkg/vm/lib/transformations/ffi_definitions.dart
+++ b/pkg/vm/lib/transformations/ffi_definitions.dart
@@ -9,7 +9,6 @@
 import 'package:front_end/src/api_unstable/vm.dart'
     show
         templateFfiEmptyStruct,
-        templateFfiEmptyStructWarning,
         templateFfiFieldAnnotation,
         templateFfiFieldCyclic,
         templateFfiFieldNoAnnotation,
@@ -427,11 +426,8 @@
 
     _annoteStructWithFields(node, types);
     if (types.isEmpty) {
-      diagnosticReporter.report(
-          templateFfiEmptyStructWarning.withArguments(node.name),
-          node.fileOffset,
-          node.name.length,
-          node.location.file);
+      diagnosticReporter.report(templateFfiEmptyStruct.withArguments(node.name),
+          node.fileOffset, node.name.length, node.location.file);
       emptyStructs.add(node);
     }
 
diff --git a/tests/ffi/vmspecific_static_checks_test.dart b/tests/ffi/vmspecific_static_checks_test.dart
index d0ee2a5..832d1ad 100644
--- a/tests/ffi/vmspecific_static_checks_test.dart
+++ b/tests/ffi/vmspecific_static_checks_test.dart
@@ -528,7 +528,7 @@
   external Pointer notEmpty;
 }
 
-class EmptyStruct extends Struct {} //# 1099: ok
+class EmptyStruct extends Struct {} //# 1099: compile-time error
 
 class EmptyStruct extends Struct {} //# 1100: compile-time error
 
diff --git a/tests/ffi_2/vmspecific_static_checks_test.dart b/tests/ffi_2/vmspecific_static_checks_test.dart
index ac72dd9..b6a0451 100644
--- a/tests/ffi_2/vmspecific_static_checks_test.dart
+++ b/tests/ffi_2/vmspecific_static_checks_test.dart
@@ -526,7 +526,7 @@
   Pointer notEmpty;
 }
 
-class EmptyStruct extends Struct {} //# 1099: ok
+class EmptyStruct extends Struct {} //# 1099: compile-time error
 
 class EmptyStruct extends Struct {} //# 1100: compile-time error