diff --git a/core/includes/bootstrap.inc b/core/includes/bootstrap.inc
index 2a28d04e08..8e5d9f6892 100644
--- a/core/includes/bootstrap.inc
+++ b/core/includes/bootstrap.inc
@@ -730,7 +730,7 @@ function _drupal_shutdown_function() {
     // Do not use foreach() here because it is possible that the callback will
     // add to the $callbacks array via drupal_register_shutdown_function().
     while ($callback = current($callbacks)) {
-      call_user_func_array($callback['callback'], $callback['arguments']);
+      $callback['callback'](...$callback['arguments']);
       next($callbacks);
     }
   }
diff --git a/core/lib/Drupal/Component/DependencyInjection/Container.php b/core/lib/Drupal/Component/DependencyInjection/Container.php
index 235cceab41..c5989bda7b 100644
--- a/core/lib/Drupal/Component/DependencyInjection/Container.php
+++ b/core/lib/Drupal/Component/DependencyInjection/Container.php
@@ -255,7 +255,7 @@ protected function createService(array $definition, $id) {
         throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
       }
 
-      $service = call_user_func_array($factory, $arguments);
+      $service = $factory(...$arguments);
     }
     else {
       $class = $this->frozen ? $definition['class'] : current($this->resolveServicesAndParameters([$definition['class']]));
diff --git a/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
index 95c4e34d0c..b8efeb0e1e 100644
--- a/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
+++ b/core/lib/Drupal/Component/DependencyInjection/PhpArrayContainer.php
@@ -76,7 +76,7 @@ protected function createService(array $definition, $id) {
         throw new RuntimeException(sprintf('Cannot create service "%s" because of invalid factory', $id));
       }
 
-      $service = call_user_func_array($factory, $arguments);
+      $service = $factory(...$arguments);
     }
     else {
       $class = $this->frozen ? $definition['class'] : current($this->resolveServicesAndParameters([$definition['class']]));
diff --git a/core/lib/Drupal/Core/Access/AccessManager.php b/core/lib/Drupal/Core/Access/AccessManager.php
index 7650fb6724..546529e62d 100644
--- a/core/lib/Drupal/Core/Access/AccessManager.php
+++ b/core/lib/Drupal/Core/Access/AccessManager.php
@@ -157,7 +157,7 @@ protected function performCheck($service_id, ArgumentsResolverInterface $argumen
     $callable = $this->checkProvider->loadCheck($service_id);
     $arguments = $arguments_resolver->getArguments($callable);
     /** @var \Drupal\Core\Access\AccessResultInterface $service_access **/
-    $service_access = call_user_func_array($callable, $arguments);
+    $service_access = $callable(...$arguments);
 
     if (!$service_access instanceof AccessResultInterface) {
       throw new AccessException("Access error in $service_id. Access services must return an object that implements AccessResultInterface.");
diff --git a/core/lib/Drupal/Core/Access/CustomAccessCheck.php b/core/lib/Drupal/Core/Access/CustomAccessCheck.php
index 353d09cd80..558ab2341f 100644
--- a/core/lib/Drupal/Core/Access/CustomAccessCheck.php
+++ b/core/lib/Drupal/Core/Access/CustomAccessCheck.php
@@ -72,7 +72,7 @@ public function access(Route $route, RouteMatchInterface $route_match, AccountIn
     $arguments_resolver = $this->argumentsResolverFactory->getArgumentsResolver($route_match, $account);
     $arguments = $arguments_resolver->getArguments($callable);
 
-    return call_user_func_array($callable, $arguments);
+    return $callable(...$arguments);
   }
 
 }
diff --git a/core/lib/Drupal/Core/Controller/TitleResolver.php b/core/lib/Drupal/Core/Controller/TitleResolver.php
index 2cf06eca7e..0dc2fe4714 100644
--- a/core/lib/Drupal/Core/Controller/TitleResolver.php
+++ b/core/lib/Drupal/Core/Controller/TitleResolver.php
@@ -55,7 +55,7 @@ public function getTitle(Request $request, Route $route) {
     if ($callback = $route->getDefault('_title_callback')) {
       $callable = $this->controllerResolver->getControllerFromDefinition($callback);
       $arguments = $this->argumentResolver->getArguments($request, $callable);
-      $route_title = call_user_func_array($callable, $arguments);
+      $route_title = $callable(...$arguments);
     }
     elseif ($title = $route->getDefault('_title')) {
       $options = [];
diff --git a/core/lib/Drupal/Core/Entity/EntityForm.php b/core/lib/Drupal/Core/Entity/EntityForm.php
index a29c392de9..5b4df3666d 100644
--- a/core/lib/Drupal/Core/Entity/EntityForm.php
+++ b/core/lib/Drupal/Core/Entity/EntityForm.php
@@ -394,7 +394,7 @@ protected function prepareInvokeAll($hook, FormStateInterface $form_state) {
         // Ensure we pass an updated translation object and form display at
         // each invocation, since they depend on form state which is alterable.
         $args = [$this->entity, $this->operation, &$form_state];
-        call_user_func_array($function, $args);
+        $function(...$args);
       }
     }
   }
diff --git a/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php
index 56ff7b1379..a00ad149f2 100644
--- a/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/EarlyRenderingControllerWrapperSubscriber.php
@@ -120,7 +120,7 @@ protected function wrapControllerExecutionInRenderContext($controller, array $ar
 
     $response = $this->renderer->executeInRenderContext($context, function () use ($controller, $arguments) {
       // Now call the actual controller, just like HttpKernel does.
-      return call_user_func_array($controller, $arguments);
+      return $controller(...$arguments);
     });
 
     // If early rendering happened, i.e. if code in the controller called
diff --git a/core/lib/Drupal/Core/Extension/ModuleHandler.php b/core/lib/Drupal/Core/Extension/ModuleHandler.php
index 1b22117ae2..4b8547570b 100644
--- a/core/lib/Drupal/Core/Extension/ModuleHandler.php
+++ b/core/lib/Drupal/Core/Extension/ModuleHandler.php
@@ -389,7 +389,7 @@ public function invoke($module, $hook, array $args = []) {
       return;
     }
     $function = $module . '_' . $hook;
-    return call_user_func_array($function, $args);
+    return $function(...$args);
   }
 
   /**
@@ -400,7 +400,7 @@ public function invokeAll($hook, array $args = []) {
     $implementations = $this->getImplementations($hook);
     foreach ($implementations as $module) {
       $function = $module . '_' . $hook;
-      $result = call_user_func_array($function, $args);
+      $result = $function(...$args);
       if (isset($result) && is_array($result)) {
         $return = NestedArray::mergeDeep($return, $result);
       }
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 6388b857c7..85d16ef85b 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -528,7 +528,7 @@ public function retrieveForm($form_id, FormStateInterface &$form_state) {
     // passed explicitly.
     $args = array_merge([$form, &$form_state], $args);
 
-    $form = call_user_func_array($callback, $args);
+    $form = $callback(...$args);
     // If the form returns a response, skip subsequent page construction by
     // throwing an exception.
     // @see Drupal\Core\EventSubscriber\EnforcedFormResponseSubscriber
diff --git a/core/lib/Drupal/Core/Menu/LocalActionManager.php b/core/lib/Drupal/Core/Menu/LocalActionManager.php
index 65b5c94afc..7d0b66ee20 100644
--- a/core/lib/Drupal/Core/Menu/LocalActionManager.php
+++ b/core/lib/Drupal/Core/Menu/LocalActionManager.php
@@ -151,7 +151,7 @@ protected function getDiscovery() {
   public function getTitle(LocalActionInterface $local_action) {
     $controller = [$local_action, 'getTitle'];
     $arguments = $this->argumentResolver->getArguments($this->requestStack->getCurrentRequest(), $controller);
-    return call_user_func_array($controller, $arguments);
+    return $controller(...$arguments);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Menu/LocalTaskManager.php b/core/lib/Drupal/Core/Menu/LocalTaskManager.php
index 6fb8bdfe93..45c87a4cab 100644
--- a/core/lib/Drupal/Core/Menu/LocalTaskManager.php
+++ b/core/lib/Drupal/Core/Menu/LocalTaskManager.php
@@ -171,7 +171,7 @@ public function getTitle(LocalTaskInterface $local_task) {
     $controller = [$local_task, 'getTitle'];
     $request = $this->requestStack->getCurrentRequest();
     $arguments = $this->argumentResolver->getArguments($request, $controller);
-    return call_user_func_array($controller, $arguments);
+    return $controller(...$arguments);
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Menu/MenuLinkTree.php b/core/lib/Drupal/Core/Menu/MenuLinkTree.php
index 52991cefa6..20f31dd32a 100644
--- a/core/lib/Drupal/Core/Menu/MenuLinkTree.php
+++ b/core/lib/Drupal/Core/Menu/MenuLinkTree.php
@@ -143,7 +143,7 @@ public function transform(array $tree, array $manipulators) {
       // argument is always the menu link tree.
       if (isset($manipulator['args'])) {
         array_unshift($manipulator['args'], $tree);
-        $tree = call_user_func_array($callable, $manipulator['args']);
+        $tree = $callable(...$manipulator['args']);
       }
       else {
         $tree = call_user_func($callable, $tree);
diff --git a/core/lib/Drupal/Core/Update/UpdateKernel.php b/core/lib/Drupal/Core/Update/UpdateKernel.php
index 4a781ff477..858734b125 100644
--- a/core/lib/Drupal/Core/Update/UpdateKernel.php
+++ b/core/lib/Drupal/Core/Update/UpdateKernel.php
@@ -112,7 +112,7 @@ protected function handleRaw(Request $request) {
     /** @var \Symfony\Component\HttpKernel\Controller\ArgumentResolverInterface $argument_resolver */
     $argument_resolver = $container->get('http_kernel.controller.argument_resolver');
     $arguments = $argument_resolver->getArguments($request, $db_update_controller);
-    return call_user_func_array($db_update_controller, $arguments);
+    return $db_update_controller(...$arguments);
   }
 
   /**
diff --git a/core/modules/color/color.module b/core/modules/color/color.module
index 8a8aa5e1b4..79766049fe 100644
--- a/core/modules/color/color.module
+++ b/core/modules/color/color.module
@@ -736,7 +736,7 @@ function _color_shift($given, $ref1, $ref2, $target) {
  */
 function _color_gd($img, $hex) {
   $c = array_merge([$img], _color_unpack($hex));
-  return call_user_func_array('imagecolorallocate', $c);
+  return imagecolorallocate(...$c);
 }
 
 /**
@@ -750,7 +750,7 @@ function _color_blend($img, $hex1, $hex2, $alpha) {
     $out[] = $in1[$i] + ($in2[$i] - $in1[$i]) * $alpha;
   }
 
-  return call_user_func_array('imagecolorallocate', $out);
+  return imagecolorallocate(...$out);
 }
 
 /**
diff --git a/core/modules/file/file.module b/core/modules/file/file.module
index 7300dd9c67..43e0a804dc 100644
--- a/core/modules/file/file.module
+++ b/core/modules/file/file.module
@@ -249,7 +249,7 @@ function file_validate(FileInterface $file, $validators = []) {
   foreach ($validators as $function => $args) {
     if (function_exists($function)) {
       array_unshift($args, $file);
-      $errors = array_merge($errors, call_user_func_array($function, $args));
+      $errors = array_merge($errors, $function(...$args));
     }
   }
 
diff --git a/core/modules/locale/src/Plugin/QueueWorker/LocaleTranslation.php b/core/modules/locale/src/Plugin/QueueWorker/LocaleTranslation.php
index 0d73a2995c..027b6eeca7 100644
--- a/core/modules/locale/src/Plugin/QueueWorker/LocaleTranslation.php
+++ b/core/modules/locale/src/Plugin/QueueWorker/LocaleTranslation.php
@@ -104,7 +104,7 @@ public function processItem($data) {
     $args = array_merge($args, [&$batch_context]);
 
     // Call the batch operation function.
-    call_user_func_array($function, $args);
+    $function(...$args);
 
     // If the batch operation is not finished we create a new queue task to
     // continue the task. This is typically the translation import task.
diff --git a/core/modules/update/src/Form/UpdateManagerInstall.php b/core/modules/update/src/Form/UpdateManagerInstall.php
index 92d3b4f65e..5ff14b6da6 100644
--- a/core/modules/update/src/Form/UpdateManagerInstall.php
+++ b/core/modules/update/src/Form/UpdateManagerInstall.php
@@ -258,7 +258,7 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
     if (fileowner($project_real_location) == fileowner($this->sitePath) && !$test_authorize) {
       $this->moduleHandler->loadInclude('update', 'inc', 'update.authorize');
       $filetransfer = new Local($this->root, \Drupal::service('file_system'));
-      $response = call_user_func_array('update_authorize_run_install', array_merge([$filetransfer], $arguments));
+      $response = update_authorize_run_install($filetransfer, ...$arguments);
       if ($response instanceof Response) {
         $form_state->setResponse($response);
       }
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php
index 5541ec27c4..32e82d4a48 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/EntityDecoupledTranslationRevisionsTest.php
@@ -489,7 +489,7 @@ protected function formatMessage($message) {
     $params = array_merge($args, $this->stepInfo);
     array_unshift($params, $this->stepIndex + 1);
     array_unshift($params, '[Step %d] ' . $message . ' (langcode: %s, default_revision: %d, untranslatable_update: %d, valid: %d)');
-    return call_user_func_array('sprintf', $params);
+    return sprintf(...$params);
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/KernelTestBase.php b/core/tests/Drupal/KernelTests/KernelTestBase.php
index a75d45758c..2e6cecf0d2 100644
--- a/core/tests/Drupal/KernelTests/KernelTestBase.php
+++ b/core/tests/Drupal/KernelTests/KernelTestBase.php
@@ -621,7 +621,7 @@ protected function assertPostConditions(): void {
     // @see _drupal_shutdown_function()
     $callbacks = &drupal_register_shutdown_function();
     while ($callback = array_shift($callbacks)) {
-      call_user_func_array($callback['callback'], $callback['arguments']);
+      $callback['callback'](...$callback['arguments']);
     }
 
     // Shut down the kernel (if bootKernel() was called).
@@ -995,7 +995,7 @@ private static function getModulesToEnable($class) {
     // defined by base classes should be sorted first. Then, merge the results
     // together.
     $modules = array_values(array_reverse($modules));
-    return call_user_func_array('array_merge_recursive', $modules);
+    return array_merge_recursive(...$modules);
   }
 
   /**
