 core/includes/common.inc                           |  8 +++--
 core/modules/comment/src/CommentLazyBuilders.php   | 40 ++++++++++++++++------
 core/modules/comment/src/CommentLinkBuilder.php    | 21 +-----------
 core/modules/comment/src/CommentViewBuilder.php    |  1 -
 .../comment/src/Tests/CommentCacheTagsTest.php     |  3 +-
 .../Tests/CommentDefaultFormatterCacheTagsTest.php |  1 +
 6 files changed, 39 insertions(+), 35 deletions(-)

diff --git a/core/includes/common.inc b/core/includes/common.inc
index 8681d81..cdbe487 100644
--- a/core/includes/common.inc
+++ b/core/includes/common.inc
@@ -856,9 +856,11 @@ function drupal_pre_render_links($element) {
       // cannot be mistakenly rendered twice).
       $child['#printed'] = TRUE;
     }
-    // Merge attachments.
-    if (isset($child['#attached'])) {
-      $element['#attached'] = BubbleableMetadata::mergeAttachments($element['#attached'], $child['#attached']);
+    // Merge bubbleable metadata.
+    if (isset($child['#cache']) || isset($child['#attached'])) {
+      BubbleableMetadata::createFromRenderArray($element)
+        ->merge(BubbleableMetadata::createFromRenderArray($child))
+        ->applyTo($element);
     }
   }
   return $element;
diff --git a/core/modules/comment/src/CommentLazyBuilders.php b/core/modules/comment/src/CommentLazyBuilders.php
index d37ab61..bb6b53d 100644
--- a/core/modules/comment/src/CommentLazyBuilders.php
+++ b/core/modules/comment/src/CommentLazyBuilders.php
@@ -170,21 +170,30 @@ protected function buildLinks(CommentInterface $entity, EntityInterface $comment
     $links = array();
     $status = $commented_entity->get($entity->getFieldName())->status;
 
+    $build = [];
+
     if ($status == CommentItemInterface::OPEN) {
-      if ($entity->access('delete')) {
+      $delete_access = $entity->access('delete', NULL, TRUE);
+      $this->renderer->addCacheableDependency($build, $delete_access);
+      if ($delete_access->isAllowed()) {
         $links['comment-delete'] = array(
           'title' => t('Delete'),
           'url' => $entity->urlInfo('delete-form'),
         );
       }
 
-      if ($entity->access('update')) {
+      $update_access = $entity->access('update', NULL, TRUE);
+      $this->renderer->addCacheableDependency($build, $update_access);
+      if ($update_access->isAllowed()) {
         $links['comment-edit'] = array(
           'title' => t('Edit'),
           'url' => $entity->urlInfo('edit-form'),
         );
       }
-      if ($entity->access('create')) {
+
+      $create_access = $entity->access('create', NULL, TRUE);
+      $this->renderer->addCacheableDependency($build, $create_access);
+      if ($create_access->isAllowed()) {
         $links['comment-reply'] = array(
           'title' => t('Reply'),
           'url' => Url::fromRoute('comment.reply', [
@@ -195,31 +204,42 @@ protected function buildLinks(CommentInterface $entity, EntityInterface $comment
           ]),
         );
       }
-      if (!$entity->isPublished() && $entity->access('approve')) {
+
+      $approve_access = $entity->access('approve', NULL, TRUE);
+      $this->renderer->addCacheableDependency($build, $entity);
+      $this->renderer->addCacheableDependency($build, $approve_access);
+      if (!$entity->isPublished() && $approve_access->isAllowed()) {
         $links['comment-approve'] = array(
           'title' => t('Approve'),
           'url' => Url::fromRoute('comment.approve', ['comment' => $entity->id()]),
         );
       }
+
+      $build['#cache']['contexts'][] = 'user.roles:authenticated';
       if (empty($links) && $this->currentUser->isAnonymous()) {
         $links['comment-forbidden']['title'] = $this->commentManager->forbiddenMessage($commented_entity, $entity->getFieldName());
       }
     }
 
     // Add translations link for translation-enabled comment bundles.
-    if ($this->moduleHandler->moduleExists('content_translation') && $this->access($entity)->isAllowed()) {
-      $links['comment-translations'] = array(
-        'title' => t('Translate'),
-        'url' => $entity->urlInfo('drupal:content-translation-overview'),
-      );
+    if ($this->moduleHandler->moduleExists('content_translation')) {
+      $translate_access = $this->access($entity);
+      $this->renderer->addCacheableDependency($build, $translate_access);
+      if ($translate_access->isAllowed()) {
+        $links['comment-translations'] = array(
+          'title' => t('Translate'),
+          'url' => $entity->urlInfo('drupal:content-translation-overview'),
+        );
+      }
     }
 
-    return array(
+    $build += array(
       '#theme' => 'links__comment__comment',
       // The "entity" property is specified to be present, so no need to check.
       '#links' => $links,
       '#attributes' => array('class' => array('links', 'inline')),
     );
+    return $build;
   }
 
   /**
diff --git a/core/modules/comment/src/CommentLinkBuilder.php b/core/modules/comment/src/CommentLinkBuilder.php
index 7ce175c..999a4d9 100644
--- a/core/modules/comment/src/CommentLinkBuilder.php
+++ b/core/modules/comment/src/CommentLinkBuilder.php
@@ -199,27 +199,8 @@ public function buildCommentedEntityLinks(FieldableEntityInterface $entity, arra
           '#attributes' => array('class' => array('links', 'inline')),
         );
         if ($view_mode == 'teaser' && $this->moduleHandler->moduleExists('history') && $this->currentUser->isAuthenticated()) {
-          $entity_links['comment__' . $field_name]['#cache']['contexts'][] = 'user';
+          $entity_links['comment__' . $field_name]['#cache']['contexts'][] = 'user.roles:authenticated';
           $entity_links['comment__' . $field_name]['#attached']['library'][] = 'comment/drupal.node-new-comments-link';
-          // Embed the metadata for the "X new comments" link (if any) on this
-          // entity.
-          $entity_links['comment__' . $field_name]['#attached']['drupalSettings']['history']['lastReadTimestamps'][$entity->id()] = (int) history_read($entity->id());
-          $new_comments = $this->commentManager->getCountNewComments($entity);
-          if ($new_comments > 0) {
-            $page_number = $this->entityManager
-              ->getStorage('comment')
-              ->getNewCommentPageNumber($entity->{$field_name}->comment_count, $new_comments, $entity);
-            $query = $page_number ? ['page' => $page_number] : NULL;
-            $value = [
-              'new_comment_count' => (int) $new_comments,
-              'first_new_comment_link' => $entity->url('canonical', [
-                'query' => $query,
-                'fragment' => 'new',
-              ]),
-            ];
-            $parents = ['comment', 'newCommentsLinks', $entity->getEntityTypeId(), $field_name, $entity->id()];
-            NestedArray::setValue($entity_links['comment__' . $field_name]['#attached']['drupalSettings'], $parents, $value);
-          }
         }
       }
     }
diff --git a/core/modules/comment/src/CommentViewBuilder.php b/core/modules/comment/src/CommentViewBuilder.php
index 66bb193..769df19 100644
--- a/core/modules/comment/src/CommentViewBuilder.php
+++ b/core/modules/comment/src/CommentViewBuilder.php
@@ -139,7 +139,6 @@ public function buildComponents(array &$build, array $entities, array $displays,
             $langcode,
             !empty($entity->in_preview),
           ]],
-          '#create_placeholder' => TRUE,
         );
       }
 
diff --git a/core/modules/comment/src/Tests/CommentCacheTagsTest.php b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
index 15142d8..a438fb3 100644
--- a/core/modules/comment/src/Tests/CommentCacheTagsTest.php
+++ b/core/modules/comment/src/Tests/CommentCacheTagsTest.php
@@ -139,7 +139,7 @@ public function testCommentEntity() {
    * {@inheritdoc}
    */
   protected function getAdditionalCacheContextsForEntity(EntityInterface $entity) {
-    return [];
+    return ['user', 'user.roles:authenticated'];
   }
 
   /**
@@ -151,6 +151,7 @@ protected function getAdditionalCacheTagsForEntity(EntityInterface $entity) {
     /** @var \Drupal\comment\CommentInterface $entity */
     return array(
       'config:filter.format.plain_text',
+      'config:user.role.anonymous',
       'user:' . $entity->getOwnerId(),
       'user_view',
     );
diff --git a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php
index 21f2065..a9e6702 100644
--- a/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php
+++ b/core/modules/comment/src/Tests/CommentDefaultFormatterCacheTagsTest.php
@@ -118,6 +118,7 @@ public function testCacheTags() {
       'comment:' . $comment->id(),
       'config:filter.format.plain_text',
       'user_view',
+      'user:1',
       'user:2',
       'config:core.entity_form_display.comment.comment.default',
       'config:field.field.comment.comment.comment_body',
