From 900242d4bf8aa10330d49ce83f86f4dadaefcc25 Mon Sep 17 00:00:00 2001 From: Michele Locati Date: Thu, 10 Sep 2026 08:36:52 +0200 Subject: [PATCH] Fix the type of the connection received by the Connection::transactional() callback Connection::transactional() calls the callback with $this, so the callback receives the actual connection instance: a closure typed with a subclass of Connection must be accepted when transactional() is called on that subclass. --- stubs/DBAL/Connection.stub | 2 +- stubs/DBAL/Connection4.stub | 2 +- .../DBAL/ConnectionTransactionalTest.php | 35 +++++++++++++++++++ .../DBAL/data/connection-transactional.php | 32 +++++++++++++++++ 4 files changed, 69 insertions(+), 2 deletions(-) create mode 100644 tests/Type/Doctrine/DBAL/ConnectionTransactionalTest.php create mode 100644 tests/Type/Doctrine/DBAL/data/connection-transactional.php diff --git a/stubs/DBAL/Connection.stub b/stubs/DBAL/Connection.stub index 1101ad59..43a2485b 100644 --- a/stubs/DBAL/Connection.stub +++ b/stubs/DBAL/Connection.stub @@ -74,7 +74,7 @@ class Connection /** * @param-immediately-invoked-callable $func - * @param Closure(self): T $func + * @param Closure(static): T $func * @return T * * @template T diff --git a/stubs/DBAL/Connection4.stub b/stubs/DBAL/Connection4.stub index bcc5528b..3d1da37b 100644 --- a/stubs/DBAL/Connection4.stub +++ b/stubs/DBAL/Connection4.stub @@ -78,7 +78,7 @@ class Connection /** * @param-immediately-invoked-callable $func - * @param Closure(self): T $func + * @param Closure(static): T $func * @return T * * @template T diff --git a/tests/Type/Doctrine/DBAL/ConnectionTransactionalTest.php b/tests/Type/Doctrine/DBAL/ConnectionTransactionalTest.php new file mode 100644 index 00000000..e3c72d5a --- /dev/null +++ b/tests/Type/Doctrine/DBAL/ConnectionTransactionalTest.php @@ -0,0 +1,35 @@ + */ + public function dataFileAsserts(): iterable + { + yield from $this->gatherAssertTypes(__DIR__ . '/data/connection-transactional.php'); + } + + /** + * @dataProvider dataFileAsserts + * @param mixed ...$args + */ + public function testFileAsserts( + string $assertType, + string $file, + ...$args + ): void + { + $this->assertFileAsserts($assertType, $file, ...$args); + } + + /** @return string[] */ + public static function getAdditionalConfigFiles(): array + { + return [__DIR__ . '/pdo.neon']; + } + +} diff --git a/tests/Type/Doctrine/DBAL/data/connection-transactional.php b/tests/Type/Doctrine/DBAL/data/connection-transactional.php new file mode 100644 index 00000000..0373f809 --- /dev/null +++ b/tests/Type/Doctrine/DBAL/data/connection-transactional.php @@ -0,0 +1,32 @@ +transactional(function ($db) { + assertType('Doctrine\DBAL\Connection', $db); + + return 1; + }); + assertType('1', $result); +}; + +function (MyConnection $connection): void { + $result = $connection->transactional(function ($db) { + assertType('ConnectionTransactional\MyConnection', $db); + + return 'foo'; + }); + assertType("'foo'", $result); + + $connection->transactional(static function (MyConnection $db): void { + }); +};