diff --git a/core/lib/Drupal/Core/Utility/LinkGenerator.php b/core/lib/Drupal/Core/Utility/LinkGenerator.php
index ab2d232..abab213 100644
--- a/core/lib/Drupal/Core/Utility/LinkGenerator.php
+++ b/core/lib/Drupal/Core/Utility/LinkGenerator.php
@@ -131,20 +131,19 @@ public function generate($text, Url $url, $collect_cacheability_metadata = FALSE
     $url->setOptions($variables['options']);
 
     // The result of the url generator is a plain-text URL. Because we are using
-    // it here in an HTML argument context, we need to encode it properly.
+    // it here in an HTML argument context, we encode it below with SafeFormat::format
     if (!$collect_cacheability_metadata) {
-      $url = SafeMarkup::checkPlain($url->toString($collect_cacheability_metadata));
+      $url = $url->toString($collect_cacheability_metadata);
     }
     else {
       $generated_url = $url->toString($collect_cacheability_metadata);
-      $url = SafeMarkup::checkPlain($generated_url->getGeneratedUrl());
+      $url = $generated_url->getGeneratedUrl();
       $generated_link = GeneratedLink::createFromObject($generated_url);
     }
 
-    // Make sure the link text is sanitized.
-    $safe_text = SafeMarkup::escape($variables['text']);
+    // $attributes are safe because all subclasses of AttributeValueBase call checkPlain in their __toString()
+    $result = SafeMarkup::format('<a href="@url"' . $attributes . '>@text</a>', ['@url' => $url, '@text' => $variables['text']]);
 
-    $result = SafeMarkup::set('<a href="' . $url . '"' . $attributes . '>' . $safe_text . '</a>');
     return $collect_cacheability_metadata ? $generated_link->setGeneratedLink($result) : $result;
   }
 
