Version 2.17.0-15.0.dev

Merge commit '763f35ace89140ce7babd5bd7619f17569efc0fe' into 'dev'
diff --git a/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart b/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
index 620289c..fc3a932 100644
--- a/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
+++ b/pkg/analyzer/lib/src/dart/error/ffi_code.g.dart
@@ -440,7 +440,7 @@
   static const FfiCode SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS = FfiCode(
     'SUBTYPE_OF_FFI_CLASS',
     "The class '{0}' can't implement '{1}'.",
-    correctionMessage: "Try extending 'Struct' or 'Union'.",
+    correctionMessage: "Try implementing 'Allocator' or 'Finalizable'.",
     uniqueName: 'SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS',
   );
 
diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
index 53ec6ae..3735ddd 100644
--- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart
+++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart
@@ -24,6 +24,7 @@
   static const _allocatorExtensionName = 'AllocatorAlloc';
   static const _arrayClassName = 'Array';
   static const _dartFfiLibraryName = 'dart.ffi';
+  static const _finalizableClassName = 'Finalizable';
   static const _isLeafParamName = 'isLeaf';
   static const _opaqueClassName = 'Opaque';
   static const _ffiNativeName = 'FfiNative';
@@ -116,7 +117,8 @@
     void checkSupertype(NamedType typename, FfiCode subtypeOfFfiCode,
         FfiCode subtypeOfStructCode) {
       final superName = typename.name.staticElement?.name;
-      if (superName == _allocatorClassName) {
+      if (superName == _allocatorClassName ||
+          superName == _finalizableClassName) {
         return;
       }
       if (typename.ffiClass != null) {
diff --git a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
index 44a6369..8e8b939 100644
--- a/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
+++ b/pkg/analyzer/lib/src/test_utilities/mock_sdk.dart
@@ -833,6 +833,9 @@
   const AbiSpecificIntegerMapping(this.mapping);
 }
 
+abstract class Finalizable {
+  factory Finalizable._() => throw UnsupportedError("");
+}
 ''',
   )
 ]);
diff --git a/pkg/analyzer/messages.yaml b/pkg/analyzer/messages.yaml
index 22d6045..4a3af55 100644
--- a/pkg/analyzer/messages.yaml
+++ b/pkg/analyzer/messages.yaml
@@ -13993,7 +13993,7 @@
   SUBTYPE_OF_FFI_CLASS_IN_IMPLEMENTS:
     sharedName: SUBTYPE_OF_FFI_CLASS
     problemMessage: "The class '{0}' can't implement '{1}'."
-    correctionMessage: "Try extending 'Struct' or 'Union'."
+    correctionMessage: "Try implementing 'Allocator' or 'Finalizable'."
     comment: |-
       Parameters:
       0: the name of the subclass
diff --git a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
index 63d6735..968dd96 100644
--- a/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
+++ b/pkg/analyzer/test/src/diagnostics/subtype_of_ffi_class_test.dart
@@ -27,6 +27,17 @@
     ]);
   }
 
+  test_Finalizable() async {
+    await assertErrorsInCode(r'''
+import 'dart:ffi';
+class C extends Finalizable {}
+''', [
+      error(FfiCode.SUBTYPE_OF_FFI_CLASS_IN_EXTENDS, 35, 11),
+      error(CompileTimeErrorCode.NO_GENERATIVE_CONSTRUCTORS_IN_SUPERCLASS, 35,
+          11),
+    ]);
+  }
+
   test_Float() async {
     await assertErrorsInCode(r'''
 import 'dart:ffi';
@@ -169,6 +180,13 @@
     ]);
   }
 
+  test_Finalizable() async {
+    await assertNoErrorsInCode(r'''
+import 'dart:ffi';
+class C implements Finalizable {}
+''');
+  }
+
   test_Float() async {
     await assertErrorsInCode(r'''
 import 'dart:ffi';
diff --git a/tools/VERSION b/tools/VERSION
index 5c751de..bce7bbe 100644
--- a/tools/VERSION
+++ b/tools/VERSION
@@ -27,5 +27,5 @@
 MAJOR 2
 MINOR 17
 PATCH 0
-PRERELEASE 14
+PRERELEASE 15
 PRERELEASE_PATCH 0
\ No newline at end of file