diff --git a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php
index 32a1362..7045195 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Theme/TwigDebugMarkupTest.php
@@ -51,8 +51,7 @@ function testTwigDebugMarkup() {
     $output = _theme('node', node_view($node));
     $this->assertTrue(strpos($output, '<!-- THEME DEBUG -->') !== FALSE, 'Twig debug markup found in theme output when debug is enabled.');
     $this->assertTrue(strpos($output, "CALL: _theme('node')") !== FALSE, 'Theme call information found.');
-    $this->assertTrue(strpos($output, 'x node--1' . $extension) !== FALSE, 'Node ID specific template shown as current template.');
-    $this->assertTrue(strpos($output, '* node' . $extension) !== FALSE, 'Base template file found.');
+    $this->assertTrue(strpos($output, 'x node--1' . $extension . PHP_EOL . '   * node--page' . $extension . PHP_EOL . '   * node' . $extension) !== FALSE, 'Suggested template files found in order and node ID specific template shown as current template.');
     $template_filename = $templates['node__1']['path'] . '/' . $templates['node__1']['template'] . $extension;
     $this->assertTrue(strpos($output, "BEGIN OUTPUT from '$template_filename'") !== FALSE, 'Full path to current template file found.');
 
@@ -60,8 +59,14 @@ function testTwigDebugMarkup() {
     // debug markup are correct.
     $node2 = $this->drupalCreateNode();
     $output = _theme('node', node_view($node2));
-    $this->assertTrue(strpos($output, '* node--2' . $extension) !== FALSE, 'Node ID specific template suggestion found.');
-    $this->assertTrue(strpos($output, 'x node' . $extension) !== FALSE, 'Base template file shown as current template.');
+    $this->assertTrue(strpos($output, '* node--2' . $extension . PHP_EOL . '   * node--page' . $extension . PHP_EOL . '   x node' . $extension) !== FALSE, 'Suggested template files found in order and base template shown as current template.');
+
+    // Create another node and make sure the template suggestions shown in the
+    // debug markup are correct.
+    $node3 = $this->drupalCreateNode();
+    $output = theme('node__foo__bar', node_view($node3));
+    $this->assertTrue(strpos($output, "CALL: theme('node__foo__bar')") !== FALSE, 'Theme call information found.');
+    $this->assertTrue(strpos($output, '* node--foo--bar' . $extension . PHP_EOL . '   * node--foo' . $extension . PHP_EOL . '   * node--3' . $extension . PHP_EOL . '   * node--page' . $extension . PHP_EOL . '   x node' . $extension) !== FALSE, 'Suggested template files found in order and base template shown as current template.');
 
     // Disable debug, rebuild the service container, and clear all caches.
     $this->settingsSet('twig_debug', FALSE);
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index a317124..dd8442e 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -57,11 +57,34 @@ function twig_render_template($template_file, $variables) {
   if (settings()->get('twig_debug', FALSE)) {
     $output['debug_prefix'] .= "\n\n<!-- THEME DEBUG -->";
     $output['debug_prefix'] .= "\n<!-- CALL: _theme('{$variables['theme_hook_original']}') -->";
+    // If there are theme suggestions, reverse the array so more specific
+    // suggestions are shown first.
+    if (!empty($variables['theme_hook_suggestions'])) {
+      $variables['theme_hook_suggestions'] = array_reverse($variables['theme_hook_suggestions']);
+    }
+    // Add debug output for directly called suggestions like
+    // '#theme' => 'comment__node__article'.
+    if (strpos($variables['theme_hook_original'], '__') !== FALSE) {
+      $derived_suggestions[] = $hook = $variables['theme_hook_original'];
+      while ($pos = strrpos($hook, '__')) {
+        $hook = substr($hook, 0, $pos);
+        $derived_suggestions[] = $hook;
+      }
+      // Get the value of the base hook (last derived suggestion) and append it
+      // to the end of all theme suggestions.
+      $base_hook = array_pop($derived_suggestions);
+      $variables['theme_hook_suggestions'] = array_merge($derived_suggestions, $variables['theme_hook_suggestions']);
+      $variables['theme_hook_suggestions'][] = $base_hook;
+    }
     if (!empty($variables['theme_hook_suggestions'])) {
       $extension = twig_extension();
       $current_template = basename($template_file);
       $suggestions = $variables['theme_hook_suggestions'];
-      $suggestions[] = $variables['theme_hook_original'];
+      // Only add the original theme hook if it wasn't a directly called
+      // suggestion.
+      if (strpos($variables['theme_hook_original'], '__') === FALSE) {
+        $suggestions[] = $variables['theme_hook_original'];
+      }
       foreach ($suggestions as &$suggestion) {
         $template = strtr($suggestion, '_', '-') . $extension;
         $prefix = ($template == $current_template) ? 'x' : '*';
