-
-
Notifications
You must be signed in to change notification settings - Fork 9.8k
[DependencyInjection] Fix #[AutowireCallable] sometimes incorrectly inlined
#62755
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: 7.3
Are you sure you want to change the base?
[DependencyInjection] Fix #[AutowireCallable] sometimes incorrectly inlined
#62755
Conversation
| } else { | ||
| $container->removeDefinition($id); | ||
| $analyzedContainer->removeDefinition($id); | ||
| if (!isset($this->autowireInline[$id])) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why doing this special case here not removing the definition ? If it can be inlined, there is no reason to keep it.
Maybe the fix is to avoid considering it as inlineable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The issue is not that the service itself is being inlined. The real problem occurs when one of the service's arguments is an AutowireCallable. If the parent service is removed, then \count($srcIds) for the argument service becomes 1, which is incorrect. As a result, the argument service is inlined when it should not be.
|
|
||
| $this->assertStringEqualsFile(self::$fixturesPath.'/php/autowire_callable_with_service_locator.php', $dumper->dump(['class' => 'Symfony_DI_PhpDumper_Test_AutowireCallable_With_ServiceLocator'])); | ||
|
|
||
| require self::$fixturesPath.'/php/autowire_callable_with_service_locator.php'; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
what about using an inline eval and skip committing the generated code?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
6b5f7d9 to
3b22fc2
Compare
When using a combination of
#[AutowireCallable]and a service locator, services may be incorrectly inlined, resulting in a broken compiled container. For example, before and after the fix (namespaces removed for readability):/** * Gets the private 'Listener1' shared autowired service. * * @return \Listener1 */ protected static function getListener1Service($container) { - return $container->privates['Listener1'] = new \Listener1(($container->services['MyInlineService'] ?? $container->get('MyInlineService'))->someMethod1(...)); + return $container->privates['Listener1'] = new \Listener1(($container->privates['MyInlineService'] ??= new \MyInlineService())->someMethod1(...)); } /** * Gets the private 'Listener2' shared autowired service. * * @return \Listener2 */ protected static function getListener2Service($container) { - return $container->privates['Listener2'] = new \Listener2((new \MyInlineService())->someMethod1(...), new \stdClass()); + return $container->privates['Listener2'] = new \Listener2(($container->privates['MyInlineService'] ??= new \MyInlineService())->someMethod2(...), new \stdClass()); }The
getListener1Service()method was broken because$container->get('MyInlineService')throws an exception:The issue is not present in 6.4.