diff --git a/core/core.services.yml b/core/core.services.yml
index 6a410c62440f2a6ecf524193ee2ce31e801f0dc1..cd647713cbaedfb88656d1b75987a4741a6c027f 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -536,7 +536,7 @@ services:
     class: Drupal\Core\Extension\RequiredModuleUninstallValidator
     tags:
       - { name: module_install.uninstall_validator }
-    arguments: ['@string_translation']
+    arguments: ['@string_translation', '@extension.list.module']
     lazy: true
   theme_handler:
     class: Drupal\Core\Extension\ThemeHandler
@@ -1265,7 +1265,7 @@ services:
     class: Drupal\Core\EventSubscriber\ConfigImportSubscriber
     tags:
       - { name: event_subscriber }
-    arguments: ['@theme_handler']
+    arguments: ['@theme_handler', '@extension.list.module']
   config_snapshot_subscriber:
     class: Drupal\Core\EventSubscriber\ConfigSnapshotSubscriber
     tags:
diff --git a/core/includes/common.inc b/core/includes/common.inc
index bc76bf774b945cd766e9db9836b56e9e07433cfb..c3f4190bf5e40d17f314245476c11baa47c6da87 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -1133,7 +1133,7 @@ function drupal_flush_all_caches() {
   \Drupal::service('twig')->invalidate();
 
   // Rebuild module and theme data.
-  $module_data = system_rebuild_module_data();
+  $module_data = \Drupal::service('extension.list.module')->reset()->getList();
   /** @var \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler */
   $theme_handler = \Drupal::service('theme_handler');
   $theme_handler->refreshInfo();
diff --git a/core/includes/install.core.inc b/core/includes/install.core.inc
index 92bf908e7ace65ae6ad46d66ee9d73b04d3484be..5258b5d19b9fde86821b15013e23d40455ec646f 100644
--- a/core/includes/install.core.inc
+++ b/core/includes/install.core.inc
@@ -1578,7 +1578,7 @@ function install_profile_modules(&$install_state) {
   install_core_entity_type_definitions();
 
   $modules = \Drupal::state()->get('install_profile_modules') ?: [];
-  $files = system_rebuild_module_data();
+  $files = \Drupal::service('extension.list.module')->getList();
   \Drupal::state()->delete('install_profile_modules');
 
   // Always install required modules first. Respect the dependencies between
@@ -2350,7 +2350,8 @@ function install_config_import_batch() {
     \Drupal::service('module_handler'),
     \Drupal::service('module_installer'),
     \Drupal::service('theme_handler'),
-    \Drupal::service('string_translation')
+    \Drupal::service('string_translation'),
+    \Drupal::service('extension.list.module')
   );
 
   try {
@@ -2421,7 +2422,8 @@ function install_config_revert_install_changes() {
       \Drupal::service('module_handler'),
       \Drupal::service('module_installer'),
       \Drupal::service('theme_handler'),
-      \Drupal::service('string_translation')
+      \Drupal::service('string_translation'),
+      \Drupal::service('extension.list.module')
     );
     try {
       $config_importer->import();
diff --git a/core/includes/update.inc b/core/includes/update.inc
index 2021a6623144c3c1248610e05d3ad17cbffbc869..4f34dbd4acd834cdbd62d1204c01ee8323a6476e 100644
--- a/core/includes/update.inc
+++ b/core/includes/update.inc
@@ -48,7 +48,7 @@ function update_check_incompatibility($name, $type = 'module') {
     // code changes that were made in the filesystem before the update script
     // was initiated.
     $themes = \Drupal::service('theme_handler')->rebuildThemeData();
-    $modules = system_rebuild_module_data();
+    $modules = \Drupal::service('extension.list.module')->reset()->getList();
   }
 
   if ($type == 'module' && isset($modules[$name])) {
diff --git a/core/lib/Drupal/Core/Config/ConfigImporter.php b/core/lib/Drupal/Core/Config/ConfigImporter.php
index 4dced73e15bfa582aafbf58fffb14d13860174d4..91317c27f8a50f7027cfd64b5c0162d1122fc0cf 100644
--- a/core/lib/Drupal/Core/Config/ConfigImporter.php
+++ b/core/lib/Drupal/Core/Config/ConfigImporter.php
@@ -3,6 +3,7 @@
 namespace Drupal\Core\Config;
 
 use Drupal\Core\Config\Importer\MissingContentEvent;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -158,6 +159,13 @@ class ConfigImporter {
    */
   protected $moduleInstaller;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Constructs a configuration import object.
    *
@@ -180,8 +188,18 @@ class ConfigImporter {
    *   The theme handler
    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
    *   The string translation service.
+   * @param \Drupal\Core\Extension\ModuleExtensionList|null $extension_list_module
+   *   The module extension list. This is left optional for BC reasons, but the
+   *   optional usage is deprecated and will become required in Drupal 9.0.0.
+   *
+   * @todo Remove null default value https://www.drupal.org/node/2947083
    */
-  public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, TranslationInterface $string_translation) {
+  public function __construct(StorageComparerInterface $storage_comparer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, TranslationInterface $string_translation, ModuleExtensionList $extension_list_module = NULL) {
+    if ($extension_list_module === NULL) {
+      @trigger_error('Invoking the ConfigImporter constructor without the module extension list parameter is deprecated in Drupal 8.8.0 and will no longer be supported in Drupal 9.0.0. The extension list parameter is now required in the ConfigImporter constructor. See https://www.drupal.org/node/2943918', E_USER_DEPRECATED);
+      $extension_list_module = \Drupal::service('extension.list.module');
+    }
+    $this->moduleExtensionList = $extension_list_module;
     $this->storageComparer = $storage_comparer;
     $this->eventDispatcher = $event_dispatcher;
     $this->configManager = $config_manager;
@@ -369,7 +387,7 @@ protected function createExtensionChangelist() {
     }
 
     // Get a list of modules with dependency weights as values.
-    $module_data = system_rebuild_module_data();
+    $module_data = $this->moduleExtensionList->getList();
     // Set the actual module weights.
     $module_list = array_combine(array_keys($module_data), array_keys($module_data));
     $module_list = array_map(function ($module) use ($module_data) {
diff --git a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php
index c0e3a4a2c8b4009cc5a00422855c88d1b8f7930c..7f2f35c32ba418fc4eb4b8b72834cf73346c4af0 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ConfigImportSubscriber.php
@@ -7,6 +7,7 @@
 use Drupal\Core\Config\ConfigImporterEvent;
 use Drupal\Core\Config\ConfigImportValidateEventSubscriberBase;
 use Drupal\Core\Config\ConfigNameException;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 
 /**
@@ -22,11 +23,11 @@ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase {
   protected $themeData;
 
   /**
-   * Module data.
+   * Module extension list.
    *
-   * @var \Drupal\Core\Extension\Extension[]
+   * @var \Drupal\Core\Extension\ModuleExtensionList
    */
-  protected $moduleData;
+  protected $moduleExtensionList;
 
   /**
    * The theme handler.
@@ -40,9 +41,12 @@ class ConfigImportSubscriber extends ConfigImportValidateEventSubscriberBase {
    *
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(ThemeHandlerInterface $theme_handler) {
+  public function __construct(ThemeHandlerInterface $theme_handler, ModuleExtensionList $extension_list_module) {
     $this->themeHandler = $theme_handler;
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -108,7 +112,7 @@ protected function validateModules(ConfigImporter $config_importer) {
     }
 
     // Get a list of modules with dependency weights as values.
-    $module_data = $this->getModuleData();
+    $module_data = $this->moduleExtensionList->getList();
     $nonexistent_modules = array_keys(array_diff_key($core_extension['module'], $module_data));
     foreach ($nonexistent_modules as $module) {
       $config_importer->logError($this->t('Unable to install the %module module since it does not exist.', ['%module' => $module]));
@@ -214,7 +218,7 @@ protected function validateDependencies(ConfigImporter $config_importer) {
     ];
 
     $theme_data = $this->getThemeData();
-    $module_data = $this->getModuleData();
+    $module_data = $this->moduleExtensionList->getList();
 
     // Validate the dependencies of all the configuration. We have to validate
     // the entire tree because existing configuration might depend on
@@ -310,18 +314,6 @@ protected function getThemeData() {
     return $this->themeData;
   }
 
-  /**
-   * Gets module data.
-   *
-   * @return \Drupal\Core\Extension\Extension[]
-   */
-  protected function getModuleData() {
-    if (!isset($this->moduleData)) {
-      $this->moduleData = system_rebuild_module_data();
-    }
-    return $this->moduleData;
-  }
-
   /**
    * Gets human readable extension names.
    *
diff --git a/core/lib/Drupal/Core/Extension/ModuleInstaller.php b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
index 77908407e5b4c1cce3c46d1b582284149d43c9a2..5246946e097bf96a5867a7f6367bd719a3428f99 100644
--- a/core/lib/Drupal/Core/Extension/ModuleInstaller.php
+++ b/core/lib/Drupal/Core/Extension/ModuleInstaller.php
@@ -83,7 +83,9 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
     $extension_config = \Drupal::configFactory()->getEditable('core.extension');
     if ($enable_dependencies) {
       // Get all module data so we can find dependencies and sort.
-      $module_data = system_rebuild_module_data();
+      // The module list needs to be reset so that it can re-scan and include
+      // any new modules that may have been added directly into the filesystem.
+      $module_data = \Drupal::service('extension.list.module')->reset()->getList();
       $module_list = $module_list ? array_combine($module_list, $module_list) : [];
       if ($missing_modules = array_diff_key($module_list, $module_data)) {
         // One or more of the given modules doesn't exist.
@@ -335,7 +337,7 @@ public function install(array $module_list, $enable_dependencies = TRUE) {
    */
   public function uninstall(array $module_list, $uninstall_dependents = TRUE) {
     // Get all module data so we can find dependencies and sort.
-    $module_data = system_rebuild_module_data();
+    $module_data = \Drupal::service('extension.list.module')->getList();
     $module_list = $module_list ? array_combine($module_list, $module_list) : [];
     if (array_diff_key($module_list, $module_data)) {
       // One or more of the given modules doesn't exist.
diff --git a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php b/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php
index d3fa533e934ad48d401aeb85772a922cf4c39215..dc5f999f167b722609fb982e580f6c541922c1a2 100644
--- a/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php
+++ b/core/lib/Drupal/Core/Extension/RequiredModuleUninstallValidator.php
@@ -12,14 +12,24 @@ class RequiredModuleUninstallValidator implements ModuleUninstallValidatorInterf
 
   use StringTranslationTrait;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Constructs a new RequiredModuleUninstallValidator.
    *
    * @param \Drupal\Core\StringTranslation\TranslationInterface $string_translation
    *   The string translation service.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(TranslationInterface $string_translation) {
+  public function __construct(TranslationInterface $string_translation, ModuleExtensionList $extension_list_module) {
     $this->stringTranslation = $string_translation;
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -41,11 +51,13 @@ public function validate($module) {
    *   The name of the module.
    *
    * @return array
-   *   The module info, or NULL if that module does not exist.
+   *   The module info, or empty array if that module does not exist.
    */
   protected function getModuleInfoByModule($module) {
-    $modules = system_rebuild_module_data();
-    return isset($modules[$module]->info) ? $modules[$module]->info : [];
+    if ($this->moduleExtensionList->exists($module)) {
+      return $this->moduleExtensionList->get($module)->info;
+    }
+    return [];
   }
 
 }
diff --git a/core/modules/book/tests/src/Kernel/BookUninstallTest.php b/core/modules/book/tests/src/Kernel/BookUninstallTest.php
index d4205ebf11bc7be8c8808745f82495be20d60bb4..13cbb4228759124fb5e0c0f733eea1ed7ba772eb 100644
--- a/core/modules/book/tests/src/Kernel/BookUninstallTest.php
+++ b/core/modules/book/tests/src/Kernel/BookUninstallTest.php
@@ -76,7 +76,7 @@ public function testBookUninstall() {
 
     $book_node->delete();
     // No nodes exist therefore the book module is not required.
-    $module_data = \Drupal::service('extension.list.module')->reset()->getList();
+    $module_data = \Drupal::service('extension.list.module')->getList();
     $this->assertFalse(isset($module_data['book']->info['required']), 'The book module is not required.');
 
     $node = Node::create(['title' => $this->randomString(), 'type' => $content_type->id()]);
diff --git a/core/modules/config/src/Form/ConfigSingleImportForm.php b/core/modules/config/src/Form/ConfigSingleImportForm.php
index a70f50fd0e9cdc00b385783a81ba1a023058bbad..3072999149dcfa0cd96b85a6ed3650b9d1949f81 100644
--- a/core/modules/config/src/Form/ConfigSingleImportForm.php
+++ b/core/modules/config/src/Form/ConfigSingleImportForm.php
@@ -13,6 +13,7 @@
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -104,6 +105,13 @@ class ConfigSingleImportForm extends ConfirmFormBase {
    */
   protected $themeHandler;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * The module installer.
    *
@@ -148,8 +156,10 @@ class ConfigSingleImportForm extends ConfirmFormBase {
    *   The module installer.
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(EntityTypeManagerInterface $entity_type_manager, StorageInterface $config_storage, RendererInterface $renderer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler) {
+  public function __construct(EntityTypeManagerInterface $entity_type_manager, StorageInterface $config_storage, RendererInterface $renderer, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, LockBackendInterface $lock, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, ModuleExtensionList $extension_list_module) {
     $this->entityTypeManager = $entity_type_manager;
     $this->configStorage = $config_storage;
     $this->renderer = $renderer;
@@ -162,6 +172,7 @@ public function __construct(EntityTypeManagerInterface $entity_type_manager, Sto
     $this->moduleHandler = $module_handler;
     $this->moduleInstaller = $module_installer;
     $this->themeHandler = $theme_handler;
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -178,7 +189,8 @@ public static function create(ContainerInterface $container) {
       $container->get('config.typed'),
       $container->get('module_handler'),
       $container->get('module_installer'),
-      $container->get('theme_handler')
+      $container->get('theme_handler'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -364,7 +376,8 @@ public function validateForm(array &$form, FormStateInterface $form_state) {
           $this->moduleHandler,
           $this->moduleInstaller,
           $this->themeHandler,
-          $this->getStringTranslation()
+          $this->getStringTranslation(),
+          $this->moduleExtensionList
         );
 
         try {
diff --git a/core/modules/config/src/Form/ConfigSync.php b/core/modules/config/src/Form/ConfigSync.php
index 8cbab3b973c816da9c7cae32773abef7cdad0219..ccbbbe9a775bca3bb5ba45f9f925dda4a119da50 100644
--- a/core/modules/config/src/Form/ConfigSync.php
+++ b/core/modules/config/src/Form/ConfigSync.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Config\ConfigImporter;
 use Drupal\Core\Config\Importer\ConfigImporterBatch;
 use Drupal\Core\Config\TypedConfigManagerInterface;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
@@ -104,6 +105,13 @@ class ConfigSync extends FormBase {
    */
   protected $renderer;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Constructs the object.
    *
@@ -129,8 +137,10 @@ class ConfigSync extends FormBase {
    *   The theme handler.
    * @param \Drupal\Core\Render\RendererInterface $renderer
    *   The renderer.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list
    */
-  public function __construct(StorageInterface $sync_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, RendererInterface $renderer) {
+  public function __construct(StorageInterface $sync_storage, StorageInterface $active_storage, StorageInterface $snapshot_storage, LockBackendInterface $lock, EventDispatcherInterface $event_dispatcher, ConfigManagerInterface $config_manager, TypedConfigManagerInterface $typed_config, ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, ThemeHandlerInterface $theme_handler, RendererInterface $renderer, ModuleExtensionList $extension_list_module) {
     $this->syncStorage = $sync_storage;
     $this->activeStorage = $active_storage;
     $this->snapshotStorage = $snapshot_storage;
@@ -142,6 +152,7 @@ public function __construct(StorageInterface $sync_storage, StorageInterface $ac
     $this->moduleInstaller = $module_installer;
     $this->themeHandler = $theme_handler;
     $this->renderer = $renderer;
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -159,7 +170,8 @@ public static function create(ContainerInterface $container) {
       $container->get('module_handler'),
       $container->get('module_installer'),
       $container->get('theme_handler'),
-      $container->get('renderer')
+      $container->get('renderer'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -328,7 +340,8 @@ public function submitForm(array &$form, FormStateInterface $form_state) {
       $this->moduleHandler,
       $this->moduleInstaller,
       $this->themeHandler,
-      $this->getStringTranslation()
+      $this->getStringTranslation(),
+      $this->moduleExtensionList
     );
     if ($config_importer->alreadyImporting()) {
       $this->messenger()->addStatus($this->t('Another request may be synchronizing configuration already.'));
diff --git a/core/modules/config/tests/src/Functional/ConfigImportAllTest.php b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
index 1d07cde0e33da09ab460c57a99fa10acfea1b8da..5ca30e1b01fa43e4f4a94c610568e7dd941cde63 100644
--- a/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportAllTest.php
@@ -45,7 +45,7 @@ protected function setUp() {
   public function testInstallUninstall() {
 
     // Get a list of modules to enable.
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
     $all_modules = array_filter($all_modules, function ($module) {
       // Filter contrib, hidden, already enabled modules and modules in the
       // Testing package.
@@ -86,7 +86,7 @@ public function testInstallUninstall() {
     // Purge the field data.
     field_purge_batch(1000);
 
-    $all_modules = system_rebuild_module_data();
+    $all_modules = \Drupal::service('extension.list.module')->getList();
 
     // Ensure that only core required modules and the install profile can not be uninstalled.
     $validation_reasons = \Drupal::service('module_installer')->validateUninstall(array_keys($all_modules));
diff --git a/core/modules/config/tests/src/Functional/ConfigImportUITest.php b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
index 715976d1622e8dc60b38a09fe0fcb515954a4c68..b3b125c22197f86bacb5f65755e15cedd4269d1b 100644
--- a/core/modules/config/tests/src/Functional/ConfigImportUITest.php
+++ b/core/modules/config/tests/src/Functional/ConfigImportUITest.php
@@ -498,7 +498,7 @@ public function testExtensionValidation() {
     $core = $sync->read('core.extension');
     // Node depends on text.
     unset($core['module']['text']);
-    $module_data = system_rebuild_module_data();
+    $module_data = $this->container->get('extension.list.module')->getList();
     $this->assertTrue(isset($module_data['node']->requires['text']), 'The Node module depends on the Text module.');
     // Bartik depends on classy.
     unset($core['theme']['classy']);
diff --git a/core/modules/config/tests/src/Kernel/ConfigUninstallViaCliImportTest.php b/core/modules/config/tests/src/Kernel/ConfigUninstallViaCliImportTest.php
index 09f5d09aa3c27413681d642be879bae273ab4a26..ae56a9c4cb97b0d456dac5237d96b8ea6d3d2c38 100644
--- a/core/modules/config/tests/src/Kernel/ConfigUninstallViaCliImportTest.php
+++ b/core/modules/config/tests/src/Kernel/ConfigUninstallViaCliImportTest.php
@@ -49,7 +49,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/modules/content_translation/tests/src/Kernel/ContentTranslationConfigImportTest.php b/core/modules/content_translation/tests/src/Kernel/ContentTranslationConfigImportTest.php
index 7e0d99faa95e7f987b112b96f6f1f52797f1c9b2..a3a3ad96e11a0f1adfe383a53632963144cca05c 100644
--- a/core/modules/content_translation/tests/src/Kernel/ContentTranslationConfigImportTest.php
+++ b/core/modules/content_translation/tests/src/Kernel/ContentTranslationConfigImportTest.php
@@ -51,7 +51,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php b/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
index afd468a5dab0509c41c10502fffc0f2667e01d70..7f723f6efa2577730a66b94c6b4ce8981836991a 100644
--- a/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
+++ b/core/modules/field/tests/src/Kernel/FieldDefinitionIntegrityTest.php
@@ -197,7 +197,7 @@ protected function checkDisplayOption($entity_type_id, $field_id, BaseFieldDefin
    *   and all modules required by any of these modules.
    */
   protected function modulesWithSubdirectory($subdirectory) {
-    $modules = system_rebuild_module_data();
+    $modules = \Drupal::service('extension.list.module')->getList();
     $modules = array_filter($modules, function (Extension $module) use ($subdirectory) {
       // Filter contrib, hidden, already enabled modules and modules in the
       // Testing package.
diff --git a/core/modules/filter/tests/src/Functional/FilterFormTest.php b/core/modules/filter/tests/src/Functional/FilterFormTest.php
index 5457912d91779e278379af6e3aeb63fa22bf007f..89b4713ac14317258c640cd397d6a3a84543be30 100644
--- a/core/modules/filter/tests/src/Functional/FilterFormTest.php
+++ b/core/modules/filter/tests/src/Functional/FilterFormTest.php
@@ -71,8 +71,6 @@ public function testFilterForm() {
     // correctly.
     // @see https://www.drupal.org/node/2387983
     \Drupal::service('module_installer')->install(['filter_test_plugin']);
-    // Force rebuild module data.
-    \Drupal::service('extension.list.module')->reset();
   }
 
   /**
diff --git a/core/modules/filter/tests/src/Kernel/FilterAPITest.php b/core/modules/filter/tests/src/Kernel/FilterAPITest.php
index ed6bff8668dd2ce1243e0b24aba3aac81ffbf2ec..3885ec4e5c77e9b80de00bf46a655a74d6bbe614 100644
--- a/core/modules/filter/tests/src/Kernel/FilterAPITest.php
+++ b/core/modules/filter/tests/src/Kernel/FilterAPITest.php
@@ -488,7 +488,7 @@ public function testDependencyRemoval() {
 
     drupal_static_reset('filter_formats');
     \Drupal::entityTypeManager()->getStorage('filter_format')->resetCache();
-    $module_data = \Drupal::service('extension.list.module')->reset()->getList();
+    $module_data = \Drupal::service('extension.list.module')->getList();
     $this->assertFalse(isset($module_data['filter_test']->info['required']), 'The filter_test module is required.');
 
     // Verify that a dependency exists on the module that provides the filter
diff --git a/core/modules/help/tests/src/Functional/HelpTest.php b/core/modules/help/tests/src/Functional/HelpTest.php
index 3965b53cde9a4368efc714635de480bce527e957..029db407da02f73fd13b6327db2069c73c8a4c24 100644
--- a/core/modules/help/tests/src/Functional/HelpTest.php
+++ b/core/modules/help/tests/src/Functional/HelpTest.php
@@ -152,7 +152,7 @@ protected function verifyHelp($response = 200) {
    */
   protected function getModuleList() {
     $modules = [];
-    $module_data = system_rebuild_module_data();
+    $module_data = $this->container->get('extension.list.module')->getList();
     foreach (\Drupal::moduleHandler()->getImplementations('help') as $module) {
       $modules[$module] = $module_data[$module]->info['name'];
     }
diff --git a/core/modules/help/tests/src/Kernel/HelpEmptyPageTest.php b/core/modules/help/tests/src/Kernel/HelpEmptyPageTest.php
index 070a95451b3bf3a888ba94a735201af8833236b4..7010fc87649437d3bbbf94f743a01f12856f8bf5 100644
--- a/core/modules/help/tests/src/Kernel/HelpEmptyPageTest.php
+++ b/core/modules/help/tests/src/Kernel/HelpEmptyPageTest.php
@@ -32,7 +32,7 @@ public function register(ContainerBuilder $container) {
    * Ensures that no URL generator is called on a page without hook_help().
    */
   public function testEmptyHookHelp() {
-    $all_modules = system_rebuild_module_data();
+    $all_modules = \Drupal::service('extension.list.module')->getList();
     $all_modules = array_filter($all_modules, function ($module) {
       // Filter contrib, hidden, already enabled modules and modules in the
       // Testing package.
diff --git a/core/modules/jsonapi/tests/src/Functional/TestCoverageTest.php b/core/modules/jsonapi/tests/src/Functional/TestCoverageTest.php
index 217d3d0d93238760c412a3df0f461f6347df9fc6..b3a2c6083b809daa89297c45e62bef7cbdd69540 100644
--- a/core/modules/jsonapi/tests/src/Functional/TestCoverageTest.php
+++ b/core/modules/jsonapi/tests/src/Functional/TestCoverageTest.php
@@ -25,7 +25,7 @@ class TestCoverageTest extends BrowserTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $all_modules = system_rebuild_module_data();
+    $all_modules = \Drupal::service('extension.list.module')->getList();
     $stable_core_modules = array_filter($all_modules, function ($module) {
       // Filter out contrib, hidden, testing, and experimental modules. We also
       // don't need to enable modules that are already enabled.
diff --git a/core/modules/language/tests/src/Kernel/OverriddenConfigImportTest.php b/core/modules/language/tests/src/Kernel/OverriddenConfigImportTest.php
index 6a243f5a098d4110a6edd634965e4ac3482aa04f..feddee68b26a0c7b111af59eb417df1768945d8b 100644
--- a/core/modules/language/tests/src/Kernel/OverriddenConfigImportTest.php
+++ b/core/modules/language/tests/src/Kernel/OverriddenConfigImportTest.php
@@ -48,7 +48,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/modules/locale/locale.compare.inc b/core/modules/locale/locale.compare.inc
index f6b79f42ec5e89d790f0fabfccf0d596084512b0..776bc752591eca8dde3a25d8f0cc52dc27148a74 100644
--- a/core/modules/locale/locale.compare.inc
+++ b/core/modules/locale/locale.compare.inc
@@ -103,7 +103,7 @@ function locale_translation_project_list() {
       'interface translation project',
       'interface translation server pattern',
     ];
-    $module_data = _locale_translation_prepare_project_list(system_rebuild_module_data(), 'module');
+    $module_data = _locale_translation_prepare_project_list(\Drupal::service('extension.list.module')->getList(), 'module');
     $theme_data = _locale_translation_prepare_project_list(\Drupal::service('theme_handler')->rebuildThemeData(), 'theme');
     $project_info = new ProjectInfo();
     $project_info->processInfoList($projects, $module_data, 'module', TRUE, $additional_whitelist);
diff --git a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
index 0ef640bbb15f55d1b9f5ae859ad6742149e23e95..82d47b95a7f5d20241fdeb9b4f0c4fe565dbe1ab 100644
--- a/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
+++ b/core/modules/rest/tests/src/Functional/EntityResource/EntityResourceRestTestCoverageTest.php
@@ -29,7 +29,7 @@ class EntityResourceRestTestCoverageTest extends BrowserTestBase {
   protected function setUp() {
     parent::setUp();
 
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
     $stable_core_modules = array_filter($all_modules, function ($module) {
       // Filter out contrib, hidden, testing, and experimental modules. We also
       // don't need to enable modules that are already enabled.
diff --git a/core/modules/system/src/Form/ModulesListForm.php b/core/modules/system/src/Form/ModulesListForm.php
index c2ade11b7a6d557d5d7f2796c98473830e4ed7d1..cabbe2ebaa4bfac243da9c4df5d8de1103732005 100644
--- a/core/modules/system/src/Form/ModulesListForm.php
+++ b/core/modules/system/src/Form/ModulesListForm.php
@@ -8,6 +8,7 @@
 use Drupal\Core\Access\AccessManagerInterface;
 use Drupal\Core\Extension\Extension;
 use Drupal\Core\Extension\InfoParserException;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Form\FormBase;
@@ -66,6 +67,13 @@ class ModulesListForm extends FormBase {
    */
   protected $permissionHandler;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * {@inheritdoc}
    */
@@ -76,7 +84,8 @@ public static function create(ContainerInterface $container) {
       $container->get('keyvalue.expirable')->get('module_list'),
       $container->get('access_manager'),
       $container->get('current_user'),
-      $container->get('user.permissions')
+      $container->get('user.permissions'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -95,8 +104,11 @@ public static function create(ContainerInterface $container) {
    *   The current user.
    * @param \Drupal\user\PermissionHandlerInterface $permission_handler
    *   The permission handler.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, AccountInterface $current_user, PermissionHandlerInterface $permission_handler) {
+  public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, AccessManagerInterface $access_manager, AccountInterface $current_user, PermissionHandlerInterface $permission_handler, ModuleExtensionList $extension_list_module) {
+    $this->moduleExtensionList = $extension_list_module;
     $this->moduleHandler = $module_handler;
     $this->moduleInstaller = $module_installer;
     $this->keyValueExpirable = $key_value_expirable;
@@ -145,7 +157,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
 
     // Sort all modules by their names.
     try {
-      $modules = system_rebuild_module_data();
+      // The module list needs to be reset so that it can re-scan and include
+      // any new modules that may have been added directly into the filesystem.
+      $modules = $this->moduleExtensionList->reset()->getList();
       uasort($modules, 'system_sort_modules_by_info_name');
     }
     catch (InfoParserException $e) {
@@ -377,7 +391,7 @@ protected function buildModuleList(FormStateInterface $form_state) {
       'experimental' => [],
     ];
 
-    $data = system_rebuild_module_data();
+    $data = $this->moduleExtensionList->getList();
     foreach ($data as $name => $module) {
       // If the module is installed there is nothing to do.
       if ($this->moduleHandler->moduleExists($name)) {
diff --git a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
index 4a66020dcca928e662726af6b1e8aa0074676f92..37717e2d275f260f5f2b32dd8205361ff89b8b91 100644
--- a/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallConfirmForm.php
@@ -6,6 +6,7 @@
 use Drupal\Core\Config\Entity\ConfigDependencyDeleteFormTrait;
 use Drupal\Core\DependencyInjection\DeprecatedServicePropertyTrait;
 use Drupal\Core\Entity\EntityTypeManagerInterface;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
@@ -64,6 +65,13 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
    */
   protected $modules = [];
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Constructs a ModulesUninstallConfirmForm object.
    *
@@ -75,12 +83,15 @@ class ModulesUninstallConfirmForm extends ConfirmFormBase {
    *   The configuration manager.
    * @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
    *   The entity type manager.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, ConfigManagerInterface $config_manager, EntityTypeManagerInterface $entity_type_manager) {
+  public function __construct(ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, ConfigManagerInterface $config_manager, EntityTypeManagerInterface $entity_type_manager, ModuleExtensionList $extension_list_module) {
     $this->moduleInstaller = $module_installer;
     $this->keyValueExpirable = $key_value_expirable;
     $this->configManager = $config_manager;
     $this->entityTypeManager = $entity_type_manager;
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -91,7 +102,8 @@ public static function create(ContainerInterface $container) {
       $container->get('module_installer'),
       $container->get('keyvalue.expirable')->get('modules_uninstall'),
       $container->get('config.manager'),
-      $container->get('entity_type.manager')
+      $container->get('entity_type.manager'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -144,7 +156,7 @@ public function buildForm(array $form, FormStateInterface $form_state) {
       return $this->redirect('system.modules_uninstall');
     }
 
-    $data = system_rebuild_module_data();
+    $data = $this->moduleExtensionList->getList();
     $form['text']['#markup'] = '<p>' . $this->t('The following modules will be completely uninstalled from your site, and <em>all data from these modules will be lost</em>!') . '</p>';
     $form['modules'] = [
       '#theme' => 'item_list',
diff --git a/core/modules/system/src/Form/ModulesUninstallForm.php b/core/modules/system/src/Form/ModulesUninstallForm.php
index 841a741e44dbf638aa0ab7ea5e6daeba5ab48dcf..9370050d15d847b0e201bc97c7e965f736cc1be3 100644
--- a/core/modules/system/src/Form/ModulesUninstallForm.php
+++ b/core/modules/system/src/Form/ModulesUninstallForm.php
@@ -2,6 +2,7 @@
 
 namespace Drupal\system\Form;
 
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ModuleInstallerInterface;
 use Drupal\Core\Form\FormBase;
@@ -37,6 +38,13 @@ class ModulesUninstallForm extends FormBase {
    */
   protected $keyValueExpirable;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * {@inheritdoc}
    */
@@ -44,7 +52,8 @@ public static function create(ContainerInterface $container) {
     return new static(
       $container->get('module_handler'),
       $container->get('module_installer'),
-      $container->get('keyvalue.expirable')->get('modules_uninstall')
+      $container->get('keyvalue.expirable')->get('modules_uninstall'),
+      $container->get('extension.list.module')
     );
   }
 
@@ -57,8 +66,11 @@ public static function create(ContainerInterface $container) {
    *   The module installer.
    * @param \Drupal\Core\KeyValueStore\KeyValueStoreExpirableInterface $key_value_expirable
    *   The key value expirable factory.
+   * @param \Drupal\Core\Extension\ModuleExtensionList $extension_list_module
+   *   The module extension list.
    */
-  public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable) {
+  public function __construct(ModuleHandlerInterface $module_handler, ModuleInstallerInterface $module_installer, KeyValueStoreExpirableInterface $key_value_expirable, ModuleExtensionList $extension_list_module) {
+    $this->moduleExtensionList = $extension_list_module;
     $this->moduleHandler = $module_handler;
     $this->moduleInstaller = $module_installer;
     $this->keyValueExpirable = $key_value_expirable;
@@ -78,10 +90,9 @@ public function buildForm(array $form, FormStateInterface $form_state) {
     // Make sure the install API is available.
     include_once DRUPAL_ROOT . '/core/includes/install.inc';
 
-    // Get a list of all available modules.
-    $modules = system_rebuild_module_data();
-    $uninstallable = array_filter($modules, function ($module) use ($modules) {
-      return empty($modules[$module->getName()]->info['required']) && $module->status;
+    // Get a list of all available modules that can be uninstalled.
+    $uninstallable = array_filter($this->moduleExtensionList->getList(), function ($module) {
+       return empty($module->info['required']) && $module->status;
     });
 
     // Include system.admin.inc so we can use the sort callbacks.
diff --git a/core/modules/system/system.install b/core/modules/system/system.install
index c6d1678834cf0fc3006e3b822149f1453831e46a..61b619dc3281c48845d1ca4091a7303ba4cbd324 100644
--- a/core/modules/system/system.install
+++ b/core/modules/system/system.install
@@ -797,7 +797,7 @@ function system_requirements($phase) {
   // Display an error if a newly introduced dependency in a module is not resolved.
   if ($phase == 'update') {
     $profile = drupal_get_profile();
-    $files = system_rebuild_module_data();
+    $files = \Drupal::service('extension.list.module')->getList();
     foreach ($files as $module => $file) {
       // Ignore disabled modules and installation profiles.
       if (!$file->status || $module == $profile) {
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 014153958eaf012727e62406ffcbdc1683182773..1371ea07217d6c17539e779093fa1c9e710f4366 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -965,7 +965,7 @@ function system_check_directory($form_element, FormStateInterface $form_state) {
  *   information for $name, if given. If no records are available, an empty
  *   array is returned.
  *
- * @see system_rebuild_module_data()
+ * @see \Drupal\Core\Extension\ModuleExtensionList::getList()
  * @see \Drupal\Core\Extension\ThemeExtensionList
  */
 function system_get_info($type, $name = NULL) {
@@ -1032,8 +1032,15 @@ function _system_rebuild_module_data() {
  *
  * @return \Drupal\Core\Extension\Extension[]
  *   Array of all available modules and their data.
+ *
+ * @deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0.
+ *   Use \Drupal::service('extension.list.module')->getList() instead.
+ *   Note: use reset() only when you really need to rescan and rebuild the list.
+ *
+ * @see https://www.drupal.org/node/2709919
  */
 function system_rebuild_module_data() {
+  @trigger_error('system_rebuild_module_data() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal::service("extension.list.module")->getList(). See https://www.drupal.org/node/2709919', E_USER_DEPRECATED);
   return \Drupal::service('extension.list.module')->reset()->getList();
 }
 
diff --git a/core/modules/system/tests/src/Functional/Module/InstallUninstallTest.php b/core/modules/system/tests/src/Functional/Module/InstallUninstallTest.php
index bcdf8ea33df97d58b8797a81b2d8b796248d1a44..fd84c4db7ec1e76cb1a1db3d120a5770bc7b8d6d 100644
--- a/core/modules/system/tests/src/Functional/Module/InstallUninstallTest.php
+++ b/core/modules/system/tests/src/Functional/Module/InstallUninstallTest.php
@@ -36,7 +36,7 @@ public function testInstallUninstall() {
     $this->assertEqual($this->container->get('state')->get('system_test_preuninstall_module'), 'module_test');
     $this->resetAll();
 
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
 
     // Test help on required modules, but do not test uninstalling.
     $required_modules = array_filter($all_modules, function ($module) {
diff --git a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
index 63229a9139800daa1d3001d7cfb4b3d16d47b7b8..bc6a580ea54cd23de204a2d06781100df9797eca 100644
--- a/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
+++ b/core/modules/system/tests/src/Kernel/Extension/ModuleHandlerTest.php
@@ -89,7 +89,6 @@ public function testDependencyResolution() {
     // Color will depend on Config, which depends on a non-existing module Foo.
     // Nothing should be installed.
     \Drupal::state()->set('module_test.dependency', 'missing dependency');
-    \Drupal::service('extension.list.module')->reset();
 
     try {
       $result = $this->moduleInstaller()->install(['color']);
@@ -104,7 +103,6 @@ public function testDependencyResolution() {
     // Fix the missing dependency.
     // Color module depends on Config. Config depends on Help module.
     \Drupal::state()->set('module_test.dependency', 'dependency');
-    \Drupal::service('extension.list.module')->reset();
 
     $result = $this->moduleInstaller()->install(['color']);
     $this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.');
@@ -136,7 +134,6 @@ public function testDependencyResolution() {
     // dependency on a specific version of Help module in its info file. Make
     // sure that Drupal\Core\Extension\ModuleInstaller::install() still works.
     \Drupal::state()->set('module_test.dependency', 'version dependency');
-    \Drupal::service('extension.list.module')->reset();
 
     $result = $this->moduleInstaller()->install(['color']);
     $this->assertTrue($result, 'ModuleInstaller::install() returns the correct value.');
@@ -171,7 +168,7 @@ public function testUninstallProfileDependencyBC() {
     drupal_get_filename('profile', $profile, 'core/profiles/' . $profile . '/' . $profile . '.info.yml');
     $this->enableModules(['module_test', $profile]);
 
-    $data = \Drupal::service('extension.list.module')->reset()->getList();
+    $data = \Drupal::service('extension.list.module')->getList();
     $this->assertFalse(isset($data[$profile]->requires[$dependency]));
     $this->assertContains($dependency, $data[$profile]->info['install']);
 
@@ -280,7 +277,6 @@ public function testUninstallContentDependency() {
     // entity_test will depend on help. This way help can not be uninstalled
     // when there is test content preventing entity_test from being uninstalled.
     \Drupal::state()->set('module_test.dependency', 'dependency');
-    \Drupal::service('extension.list.module')->reset();
 
     // Create an entity so that the modules can not be disabled.
     $entity = EntityTest::create(['name' => $this->randomString()]);
@@ -319,7 +315,7 @@ public function testUninstallContentDependency() {
    */
   public function testModuleMetaData() {
     // Generate the list of available modules.
-    $modules = system_rebuild_module_data();
+    $modules = $this->container->get('extension.list.module')->getList();
     // Check that the mtime field exists for the system module.
     $this->assertTrue(!empty($modules['system']->info['mtime']), 'The system.info.yml file modification time field is present.');
     // Use 0 if mtime isn't present, to avoid an array index notice.
diff --git a/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php b/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php
index ebdac3ce0dbf75ce2b97b600ca52d15046a77fe8..ee5fbf6adf8a57b428206cde5669413745119dd5 100644
--- a/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php
+++ b/core/modules/system/tests/src/Kernel/System/InfoAlterTest.php
@@ -22,14 +22,14 @@ class InfoAlterTest extends KernelTestBase {
    */
   public function testSystemInfoAlter() {
     \Drupal::state()->set('module_required_test.hook_system_info_alter', TRUE);
-    $info = system_rebuild_module_data();
+    $info = \Drupal::service('extension.list.module')->getList();
     $this->assertFalse(isset($info['node']->info['required']), 'Before the module_required_test is installed the node module is not required.');
 
     // Enable the test module.
     \Drupal::service('module_installer')->install(['module_required_test'], FALSE);
     $this->assertTrue(\Drupal::moduleHandler()->moduleExists('module_required_test'), 'Test required module is enabled.');
 
-    $info = system_rebuild_module_data();
+    $info = \Drupal::service('extension.list.module')->getList();
     $this->assertTrue($info['node']->info['required'], 'After the module_required_test is installed the node module is required.');
   }
 
diff --git a/core/modules/system/tests/src/Kernel/SystemFunctionsLegacyTest.php b/core/modules/system/tests/src/Kernel/SystemFunctionsLegacyTest.php
new file mode 100644
index 0000000000000000000000000000000000000000..fd97b0ecfe23bcc037322811064fb012df83d85f
--- /dev/null
+++ b/core/modules/system/tests/src/Kernel/SystemFunctionsLegacyTest.php
@@ -0,0 +1,28 @@
+<?php
+
+namespace Drupal\Tests\system\Kernel;
+
+use Drupal\KernelTests\KernelTestBase;
+
+/**
+ * Tests deprecated system module functions.
+ *
+ * @group system
+ * @group legacy
+ */
+class SystemFunctionsLegacyTest extends KernelTestBase {
+
+  /**
+   * {@inheritdoc}
+   */
+  protected static $modules = ['system'];
+
+  /**
+   * @expectedDeprecation system_rebuild_module_data() is deprecated in Drupal 8.8.0 and will be removed before Drupal 9.0.0. Instead, you should use \Drupal::service("extension.list.module")->getList(). See https://www.drupal.org/node/2709919
+   * @see system_rebuild_module_data()
+   */
+  public function testSystemRebuildModuleDataDeprecation() {
+    system_rebuild_module_data();
+  }
+
+}
diff --git a/core/modules/update/src/UpdateManager.php b/core/modules/update/src/UpdateManager.php
index 07416915af6bd72f664ffa51b91c1b4dceb60e30..cbb74d703de097ec1c2c4378a273d9806d6a3a8b 100644
--- a/core/modules/update/src/UpdateManager.php
+++ b/core/modules/update/src/UpdateManager.php
@@ -4,6 +4,7 @@
 
 use Drupal\Core\Config\ConfigFactoryInterface;
 use Drupal\Core\DependencyInjection\DependencySerializationTrait;
+use Drupal\Core\Extension\ModuleExtensionList;
 use Drupal\Core\Extension\ModuleHandlerInterface;
 use Drupal\Core\Extension\ThemeHandlerInterface;
 use Drupal\Core\KeyValueStore\KeyValueFactoryInterface;
@@ -67,6 +68,13 @@ class UpdateManager implements UpdateManagerInterface {
    */
   protected $themeHandler;
 
+  /**
+   * The module extension list.
+   *
+   * @var \Drupal\Core\Extension\ModuleExtensionList
+   */
+  protected $moduleExtensionList;
+
   /**
    * Constructs a UpdateManager.
    *
@@ -82,8 +90,11 @@ class UpdateManager implements UpdateManagerInterface {
    *   The expirable key/value factory.
    * @param \Drupal\Core\Extension\ThemeHandlerInterface $theme_handler
    *   The theme handler.
+   * @param \Drupal\Core\Extension\ModuleExtensionList|null $extension_list_module
+   *   The module extension list. This is left optional for BC reasons, but the
+   *   optional usage is deprecated and will become required in Drupal 9.0.0.
    */
-  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, UpdateProcessorInterface $update_processor, TranslationInterface $translation, KeyValueFactoryInterface $key_value_expirable_factory, ThemeHandlerInterface $theme_handler) {
+  public function __construct(ConfigFactoryInterface $config_factory, ModuleHandlerInterface $module_handler, UpdateProcessorInterface $update_processor, TranslationInterface $translation, KeyValueFactoryInterface $key_value_expirable_factory, ThemeHandlerInterface $theme_handler, ModuleExtensionList $extension_list_module = NULL) {
     $this->updateSettings = $config_factory->get('update.settings');
     $this->moduleHandler = $module_handler;
     $this->updateProcessor = $update_processor;
@@ -92,6 +103,11 @@ public function __construct(ConfigFactoryInterface $config_factory, ModuleHandle
     $this->themeHandler = $theme_handler;
     $this->availableReleasesTempStore = $key_value_expirable_factory->get('update_available_releases');
     $this->projects = [];
+    if ($extension_list_module === NULL) {
+      @trigger_error('Invoking the UpdateManager constructor without the module extension list parameter is deprecated in Drupal 8.8.0 and will no longer be supported in Drupal 9.0.0. The extension list parameter is now required in the ConfigImporter constructor. See https://www.drupal.org/node/2943918', E_USER_DEPRECATED);
+      $extension_list_module = \Drupal::service('extension.list.module');
+    }
+    $this->moduleExtensionList = $extension_list_module;
   }
 
   /**
@@ -129,7 +145,7 @@ public function getProjects() {
       $this->projects = $this->projectStorage('update_project_projects');
       if (empty($this->projects)) {
         // Still empty, so we have to rebuild.
-        $module_data = system_rebuild_module_data();
+        $module_data = $this->moduleExtensionList->reset()->getList();
         $theme_data = $this->themeHandler->rebuildThemeData();
         $project_info = new ProjectInfo();
         $project_info->processInfoList($this->projects, $module_data, 'module', TRUE);
diff --git a/core/modules/update/tests/src/Functional/UpdateContribTest.php b/core/modules/update/tests/src/Functional/UpdateContribTest.php
index e16a3df77bc200eb21072d3b6be5a7bb194b3b00..aa0d44abd653f5e869c15f42caf23b6b474e3da7 100644
--- a/core/modules/update/tests/src/Functional/UpdateContribTest.php
+++ b/core/modules/update/tests/src/Functional/UpdateContribTest.php
@@ -120,7 +120,7 @@ public function testUpdateContribBasic() {
    * project. We need to make sure that we see the "BBB" project before the
    * "CCC" project, even though "CCC" includes a module that's processed first
    * if you sort alphabetically by module name (which is the order we see things
-   * inside system_rebuild_module_data() for example).
+   * inside \Drupal\Core\Extension\ExtensionList::getList() for example).
    */
   public function testUpdateContribOrder() {
     // We want core to be version 8.0.0.
diff --git a/core/modules/update/update.services.yml b/core/modules/update/update.services.yml
index fc176d6f7bed9dbffea5fca8207fc4b9ba6d5173..767a1d1f3018344f6a39b51d8f53a456cd29483b 100644
--- a/core/modules/update/update.services.yml
+++ b/core/modules/update/update.services.yml
@@ -6,7 +6,7 @@ services:
       - { name: access_check, applies_to: _access_update_manager }
   update.manager:
     class: Drupal\update\UpdateManager
-    arguments: ['@config.factory', '@module_handler', '@update.processor', '@string_translation', '@keyvalue.expirable', '@theme_handler']
+    arguments: ['@config.factory', '@module_handler', '@update.processor', '@string_translation', '@keyvalue.expirable', '@theme_handler', '@extension.list.module']
   update.processor:
     class: Drupal\update\UpdateProcessor
     arguments: ['@config.factory', '@queue', '@update.fetcher', '@state', '@private_key', '@keyvalue', '@keyvalue.expirable']
diff --git a/core/modules/user/src/PermissionHandler.php b/core/modules/user/src/PermissionHandler.php
index 1f07b25d9509e2a0e618713fbe0c51cd8a628cbe..056c435dffdf91db70e0443674cce55efb36ac0e 100644
--- a/core/modules/user/src/PermissionHandler.php
+++ b/core/modules/user/src/PermissionHandler.php
@@ -229,13 +229,4 @@ protected function getModuleNames() {
     return $modules;
   }
 
-  /**
-   * Wraps system_rebuild_module_data()
-   *
-   * @return \Drupal\Core\Extension\Extension[]
-   */
-  protected function systemRebuildModuleData() {
-    return system_rebuild_module_data();
-  }
-
 }
diff --git a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
index 3cc76f8fa2825e3609213647925a576a26d73f07..28ba38adee8347df4c4db17e5b5cc16c8e229fd7 100644
--- a/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
+++ b/core/modules/user/tests/src/Unit/PermissionHandlerTest.php
@@ -29,7 +29,7 @@ class PermissionHandlerTest extends UnitTestCase {
   /**
    * The tested permission handler.
    *
-   * @var \Drupal\Tests\user\Unit\TestPermissionHandler|\Drupal\user\PermissionHandler
+   * @var \Drupal\user\PermissionHandler
    */
   protected $permissionHandler;
 
@@ -142,10 +142,7 @@ public function testBuildPermissionsYaml() {
     $this->controllerResolver->expects($this->never())
       ->method('getControllerFromDefinition');
 
-    $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
-
-    // Setup system_rebuild_module_data().
-    $this->permissionHandler->setSystemRebuildModuleData($extensions);
+    $this->permissionHandler = new PermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
 
     $actual_permissions = $this->permissionHandler->getPermissions();
     $this->assertPermissions($actual_permissions);
@@ -206,7 +203,7 @@ public function testBuildPermissionsSortPerModule() {
       ->method('getModuleList')
       ->willReturn(array_flip($modules));
 
-    $permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
+    $permissionHandler = new PermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
     $actual_permissions = $permissionHandler->getPermissions();
     $this->assertEquals(['access_module_a4', 'access_module_a1', 'access_module_a2', 'access_module_a3'],
       array_keys($actual_permissions));
@@ -287,10 +284,7 @@ public function testBuildPermissionsYamlCallback() {
       ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescriptionRestrictAccess')
       ->willReturn([new TestPermissionCallbacks(), 'titleDescriptionRestrictAccess']);
 
-    $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
-
-    // Setup system_rebuild_module_data().
-    $this->permissionHandler->setSystemRebuildModuleData($extensions);
+    $this->permissionHandler = new PermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
 
     $actual_permissions = $this->permissionHandler->getPermissions();
     $this->assertPermissions($actual_permissions);
@@ -341,10 +335,7 @@ public function testPermissionsYamlStaticAndCallback() {
       ->with('Drupal\\user\\Tests\\TestPermissionCallbacks::titleDescription')
       ->willReturn([new TestPermissionCallbacks(), 'titleDescription']);
 
-    $this->permissionHandler = new TestPermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
-
-    // Setup system_rebuild_module_data().
-    $this->permissionHandler->setSystemRebuildModuleData($extensions);
+    $this->permissionHandler = new PermissionHandler($this->moduleHandler, $this->stringTranslation, $this->controllerResolver);
 
     $actual_permissions = $this->permissionHandler->getPermissions();
 
@@ -377,25 +368,6 @@ protected function assertPermissions(array $actual_permissions) {
 
 }
 
-class TestPermissionHandler extends PermissionHandler {
-
-  /**
-   * Test module data.
-   *
-   * @var array
-   */
-  protected $systemModuleData;
-
-  protected function systemRebuildModuleData() {
-    return $this->systemModuleData;
-  }
-
-  public function setSystemRebuildModuleData(array $extensions) {
-    $this->systemModuleData = $extensions;
-  }
-
-}
-
 class TestPermissionCallbacks {
 
   public function singleDescription() {
diff --git a/core/tests/Drupal/KernelTests/Core/Asset/ResolvedLibraryDefinitionsFilesMatchTest.php b/core/tests/Drupal/KernelTests/Core/Asset/ResolvedLibraryDefinitionsFilesMatchTest.php
index 321443d4db16805b2d3240f589adc07d591b831b..af0ffd89ed7457c59bf64dfe327c625d13f8ef58 100644
--- a/core/tests/Drupal/KernelTests/Core/Asset/ResolvedLibraryDefinitionsFilesMatchTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Asset/ResolvedLibraryDefinitionsFilesMatchTest.php
@@ -99,7 +99,7 @@ protected function setUp() {
     $this->container->get('theme_installer')->install($this->allThemes);
 
     // Enable all core modules.
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
     $all_modules = array_filter($all_modules, function ($module) {
       // Filter contrib, hidden, already enabled modules and modules in the
       // Testing package.
diff --git a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
index e19911c535836f727d3601b41e3c281c9a40b53d..48a031606172ff1ff0c511cbcb62beee080f62a7 100644
--- a/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Bootstrap/GetFilenameTest.php
@@ -30,8 +30,6 @@ public function register(ContainerBuilder $container) {
    * Tests that drupal_get_filename() works when the file is not in database.
    */
   public function testDrupalGetFilename() {
-    system_rebuild_module_data();
-
     // Retrieving the location of a module.
     $this->assertIdentical(drupal_get_filename('module', 'system'), 'core/modules/system/system.info.yml');
 
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigDependencyTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigDependencyTest.php
index 2889d9d65f96ebc17cb02e716e004e5089e7165c..fb310bd32de0e0ff43acf573636c63d466353556 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigDependencyTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigDependencyTest.php
@@ -217,10 +217,6 @@ public function testConfigEntityUninstall() {
       ]
     );
     $entity2->save();
-    // Perform a module rebuild so we can know where the node module is located
-    // and uninstall it.
-    // @todo Remove as part of https://www.drupal.org/node/2186491
-    system_rebuild_module_data();
     // Test that doing a config uninstall of the node module deletes entity2
     // since it is dependent on entity1 which is dependent on the node module.
     $config_manager->uninstall('module', 'node');
@@ -359,10 +355,6 @@ public function testConfigEntityUninstallComplex(array $entity_id_suffixes) {
     $this->assertEqual($entity_4->uuid(), $config_entities['delete'][0]->uuid(), 'Entity 4 will be deleted.');
     $this->assertEqual($entity_5->uuid(), $config_entities['update'][1]->uuid(), 'Entity 5 is updated.');
 
-    // Perform a module rebuild so we can know where the node module is located
-    // and uninstall it.
-    // @todo Remove as part of https://www.drupal.org/node/2186491
-    system_rebuild_module_data();
     // Perform the uninstall.
     $config_manager->uninstall('module', 'node');
 
@@ -476,10 +468,6 @@ public function testConfigEntityUninstallThirdParty() {
     $this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_2->id()]);
     $this->assertSame(['config' => [], 'content' => [], 'module' => ['node'], 'theme' => []], $called[$entity_4->id()]);
 
-    // Perform a module rebuild so we can know where the node module is located
-    // and uninstall it.
-    // @todo Remove as part of https://www.drupal.org/node/2186491
-    system_rebuild_module_data();
     // Perform the uninstall.
     $config_manager->uninstall('module', 'node');
 
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
index 5b40e3318d087ff71b478521a802b4b19c4413d4..3ff2dea5989fbee51b821e299fdc50cf36c84b71 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRecreateTest.php
@@ -50,7 +50,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
index 7378da161e8c104448843d0f4138ad35e9e158e4..4ec352e57d581e7ee4dcce5af13053d39a1fcc4a 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImportRenameValidationTest.php
@@ -55,7 +55,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php
index a4b084756342f8886d13e1a8a7dbcfe9bbcffe03..c67e0425dae03575240dea6c9834a6d188aa1e8e 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterMissingContentTest.php
@@ -55,7 +55,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
index 70dbb874c96f90f3e9300342caaa80d04a11aa21..29ff1fb5968314e4f28d596b45df1ab71b22cfe7 100644
--- a/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Config/ConfigImporterTest.php
@@ -60,7 +60,8 @@ protected function setUp() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
   }
 
diff --git a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php
index 1b22b20a5ce9157ab580baa83aa9ec5caf5c3d04..188e9d1a495f6396c193e9816d93eb772ed3abbf 100644
--- a/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Entity/ContentEntityNullStorageTest.php
@@ -63,7 +63,8 @@ public function testDeleteThroughImport() {
       $this->container->get('module_handler'),
       $this->container->get('module_installer'),
       $this->container->get('theme_handler'),
-      $this->container->get('string_translation')
+      $this->container->get('string_translation'),
+      $this->container->get('extension.list.module')
     );
 
     // Delete the contact message in sync.
diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php
index 0fca6d2e6ecfdfa9bf4c2dcb5d786e5957f91a84..54a4b7779ba0f23e190bc6af15bbb2ffff463e25 100644
--- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleConfigureRouteTest.php
@@ -38,7 +38,7 @@ class ModuleConfigureRouteTest extends KernelTestBase {
   protected function setUp() {
     parent::setUp();
     $this->routeProvider = \Drupal::service('router.route_provider');
-    $this->moduleInfo = system_rebuild_module_data();
+    $this->moduleInfo = \Drupal::service('extension.list.module')->getList();
   }
 
   /**
diff --git a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
index 7ffe65c9fc33392bf7b6420f5596cc2b0f78346f..b453afc92ffc27417eefb85b7a23ee8c04ca463f 100644
--- a/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Extension/ModuleInstallerTest.php
@@ -15,15 +15,6 @@
  */
 class ModuleInstallerTest extends KernelTestBase {
 
-  /**
-   * Modules to install.
-   *
-   * The System module is required because system_rebuild_module_data() is used.
-   *
-   * @var array
-   */
-  public static $modules = ['system'];
-
   /**
    * Tests that routes are rebuilt during install and uninstall of modules.
    *
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
index 049438b25402676e61f12ac83e0c9d83b7e8b01f..795ea334664b577d3f12e01559aa6e7307a04866 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/StableLibraryOverrideTest.php
@@ -60,7 +60,7 @@ protected function setUp() {
     $this->container->get('theme_installer')->install(['stable']);
 
     // Enable all core modules.
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
     $all_modules = array_filter($all_modules, function ($module) {
       // Filter contrib, hidden, experimental, already enabled modules, and
       // modules in the Testing package.
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php b/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
index 88bbde23a09c90ada1fad9b2d234981b3f772f2f..73d467ce67b93daa6ef57d24338c7bffaaf67554 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/StableTemplateOverrideTest.php
@@ -56,11 +56,8 @@ protected function setUp() {
    * Installs all core modules.
    */
   protected function installAllModules() {
-    // Needed for system_rebuild_module_data().
-    include_once $this->root . '/core/modules/system/system.module';
-
     // Enable all core modules.
-    $all_modules = system_rebuild_module_data();
+    $all_modules = $this->container->get('extension.list.module')->getList();
     $all_modules = array_filter($all_modules, function ($module) {
       // Filter contrib, hidden, experimental, already enabled modules, and
       // modules in the Testing package.
diff --git a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
index 5c650d4f4684a0520d8fe5df16b852833a20f9f0..180b708a376631e52783149467a2d73fdbe50cbb 100644
--- a/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
+++ b/core/tests/Drupal/KernelTests/Core/Theme/ThemeInstallerTest.php
@@ -311,9 +311,7 @@ public function testThemeInfoAlter() {
     $themes = $this->themeHandler()->listInfo();
     $this->assertFalse(isset($themes[$name]->info['regions']['test_region']));
 
-    // Rebuild module data so we know where module_test is located.
-    // @todo Remove as part of https://www.drupal.org/node/2186491
-    system_rebuild_module_data();
+    // Install module_test.
     $this->moduleInstaller()->install(['module_test'], FALSE);
     $this->assertTrue($this->moduleHandler()->moduleExists('module_test'));
 
diff --git a/core/tests/Drupal/Tests/ConfigTestTrait.php b/core/tests/Drupal/Tests/ConfigTestTrait.php
index 45a7c728bf509f1e71e07a9e9196ae6d2cfb2c6d..139f7f36270b42d585a68d45446fe4d36ae9e1f2 100644
--- a/core/tests/Drupal/Tests/ConfigTestTrait.php
+++ b/core/tests/Drupal/Tests/ConfigTestTrait.php
@@ -36,7 +36,8 @@ protected function configImporter() {
         $this->container->get('module_handler'),
         $this->container->get('module_installer'),
         $this->container->get('theme_handler'),
-        $this->container->get('string_translation')
+        $this->container->get('string_translation'),
+        $this->container->get('extension.list.module')
       );
     }
     // Always recalculate the changelist when called.