diff --git a/pkg/analyzer/lib/src/generated/ffi_verifier.dart b/pkg/analyzer/lib/src/generated/ffi_verifier.dart index a0410891e1d..d21153132f9 100644 --- a/pkg/analyzer/lib/src/generated/ffi_verifier.dart +++ b/pkg/analyzer/lib/src/generated/ffi_verifier.dart @@ -674,8 +674,13 @@ class FfiVerifier extends RecursiveAstVisitor { // Receiver can only be Pointer if the class extends // NativeFieldWrapperClass1. if (ffiSignature.normalParameterTypes[0].isPointer) { - var cls = declarationElement.enclosingElement as InterfaceElement; - if (!_extendsNativeFieldWrapperClass1(cls.thisType)) { + var enclosingElement = declarationElement.enclosingElement; + var receiverType = switch (enclosingElement) { + InterfaceElement() => enclosingElement.thisType, + ExtensionElement(extendedType: InterfaceType type) => type, + _ => null, + }; + if (!_extendsNativeFieldWrapperClass1(receiverType)) { _diagnosticReporter.report( diag.ffiNativeOnlyClassesExtendingNativefieldwrapperclass1CanBePointer .at(errorToken), diff --git a/tests/ffi/static_checks/regress_62716_test.dart b/tests/ffi/static_checks/regress_62716_test.dart new file mode 100644 index 00000000000..dcebc67a1dd --- /dev/null +++ b/tests/ffi/static_checks/regress_62716_test.dart @@ -0,0 +1,43 @@ +// Copyright (c) 2026, the Dart project authors. Please see the AUTHORS file +// 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. + +// Regression test for https://github.com/dart-lang/sdk/issues/62716 + +import 'dart:ffi'; +import 'dart:nativewrappers'; + +extension on int { + @Native)>(symbol: 'x') + // [error column 4] + // [cfe] Only classes extending NativeFieldWrapperClass1 can be passed as Pointer. + external void x(); + // ^ + // [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER +} + +extension on dynamic { + @Native)>(symbol: 'z') + external void z(); + // ^ + // [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER + // [cfe] Expected type 'void Function(dynamic)' to be 'void Function(Pointer)', which is the Dart type corresponding to 'NativeFunction)>'. +} + +extension on void Function() { + @Native)>(symbol: 'f') + external void f(); + // ^ + // [analyzer] COMPILE_TIME_ERROR.FFI_NATIVE_ONLY_CLASSES_EXTENDING_NATIVEFIELDWRAPPERCLASS1_CAN_BE_POINTER + // [cfe] Expected type 'void Function(void Function())' to be 'void Function(Pointer)', which is the Dart type corresponding to 'NativeFunction)>'. + + @Native(symbol: 'f2') + external void f2(); +} + +extension on NativeFieldWrapperClass1 { + @Native)>(symbol: 'y') + external void y(); +} + +void main() {}