diff --git a/core/lib/Drupal/Component/Utility/SafeMarkup.php b/core/lib/Drupal/Component/Utility/SafeMarkup.php
index b2d00a3090154c6e4b0637b689672f4afda2a02e..5b346a98676a4f705bb16db8f12ae15f1e36686f 100644
--- a/core/lib/Drupal/Component/Utility/SafeMarkup.php
+++ b/core/lib/Drupal/Component/Utility/SafeMarkup.php
@@ -40,6 +40,7 @@ class SafeMarkup {
    * @see https://www.drupal.org/node/2549395
    */
   public static function isSafe($string, $strategy = 'html') {
+    @trigger_error('SafeMarkup::isSafe() is scheduled for removal in Drupal 9.0.0. Instead, you should just check if a variable is an instance of \Drupal\Component\Render\MarkupInterface. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
     return $string instanceof MarkupInterface;
   }
 
@@ -66,6 +67,7 @@ public static function isSafe($string, $strategy = 'html') {
    * @see drupal_validate_utf8()
    */
   public static function checkPlain($text) {
+    @trigger_error('SafeMarkup::checkPlain() is scheduled for removal in Drupal 9.0.0. Rely on Twig\'s auto-escaping feature, or use the @link theme_render #plain_text @endlink key when constructing a render array that contains plain text in order to use the renderer\'s auto-escaping feature. If neither of these are possible, \Drupal\Component\Utility\Html::escape() can be used in places where explicit escaping is needed. See https://www.drupal.org/node/2549395.', E_USER_DEPRECATED);
     return new HtmlEscapedText($text);
   }
 
diff --git a/core/lib/Drupal/Core/Render/Markup.php b/core/lib/Drupal/Core/Render/Markup.php
index 6a2f2914da64a2d9a773820082a274a4cb15db5c..0947f8fc675eae35715eed1704c3430f59ee1395 100644
--- a/core/lib/Drupal/Core/Render/Markup.php
+++ b/core/lib/Drupal/Core/Render/Markup.php
@@ -18,7 +18,6 @@
  *
  * @see \Drupal\Core\Template\TwigExtension::escapeFilter
  * @see \Twig_Markup
- * @see \Drupal\Component\Utility\SafeMarkup
  */
 final class Markup implements MarkupInterface, \Countable {
   use MarkupTrait;
diff --git a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
index 8a5dc05d75084a5242064daece5b060e0387abac..5286242281a5c94b047163a4e1f96f163acd04bc 100644
--- a/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
+++ b/core/lib/Drupal/Core/Template/TwigNodeVisitor.php
@@ -43,7 +43,7 @@ protected function doLeaveNode(\Twig_Node $node, \Twig_Environment $env) {
     elseif ($node instanceof \Twig_Node_Expression_Filter) {
       $name = $node->getNode('filter')->getAttribute('value');
       if ('escape' == $name || 'e' == $name) {
-        // Use our own escape filter that is SafeMarkup aware.
+        // Use our own escape filter that is MarkupInterface aware.
         $node->getNode('filter')->setAttribute('value', 'drupal_escape');
 
         // Store that we have a filter active already that knows
diff --git a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
index e7a7dfc9ddff08e88c4ae368433898457fa889d4..704f454586a3db604b3dd2dd50c5bb1e95510c3a 100644
--- a/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/src/Tests/ContentTranslationUITestBase.php
@@ -37,8 +37,7 @@ abstract class ContentTranslationUITestBase extends ContentTranslationTestBase {
   protected $testLanguageSelector = TRUE;
 
   /**
-   * Flag that tells whether the HTML escaping of all languages works or not
-   * after SafeMarkup change.
+   * Flag to determine if "all languages" rendering is tested.
    *
    * @var bool
    */
@@ -117,8 +116,7 @@ protected function doTestBasicTranslation() {
     ], ['language' => $language]);
     $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), $this->getFormSubmitActionForNewTranslation($entity, $langcode));
 
-    // Assert that HTML is escaped in "all languages" in UI after SafeMarkup
-    // change.
+    // Assert that HTML is not escaped unexpectedly.
     if ($this->testHTMLEscapeForAllLanguages) {
       $this->assertNoRaw('<span class="translation-entity-all-languages">(all languages)</span>');
       $this->assertRaw('<span class="translation-entity-all-languages">(all languages)</span>');
diff --git a/core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php b/core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php
index c755ac4906e773bca04499babb8379783aad2e94..989398e7986873d03800523eea5ab788f409d53b 100644
--- a/core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php
+++ b/core/modules/content_translation/tests/src/Functional/ContentTranslationUITestBase.php
@@ -35,8 +35,7 @@ abstract class ContentTranslationUITestBase extends ContentTranslationTestBase {
   protected $testLanguageSelector = TRUE;
 
   /**
-   * Flag that tells whether the HTML escaping of all languages works or not
-   * after SafeMarkup change.
+   * Flag to determine if "all languages" rendering is tested.
    *
    * @var bool
    */
@@ -115,8 +114,7 @@ protected function doTestBasicTranslation() {
     ], ['language' => $language]);
     $this->drupalPostForm($add_url, $this->getEditValues($values, $langcode), $this->getFormSubmitActionForNewTranslation($entity, $langcode));
 
-    // Assert that HTML is escaped in "all languages" in UI after SafeMarkup
-    // change.
+    // Assert that HTML is not escaped unexpectedly.
     if ($this->testHTMLEscapeForAllLanguages) {
       $this->assertNoRaw('&lt;span class=&quot;translation-entity-all-languages&quot;&gt;(all languages)&lt;/span&gt;');
       $this->assertRaw('<span class="translation-entity-all-languages">(all languages)</span>');
diff --git a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
index f811c16c15d82829d02f7d6642bfe5793abf7560..2b7d677dea7cd98ad78855331199149ab4c46f90 100644
--- a/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
+++ b/core/tests/Drupal/Tests/Component/Utility/SafeMarkupTest.php
@@ -18,6 +18,7 @@
  * Tests marking strings as safe.
  *
  * @group Utility
+ * @group legacy
  * @coversDefaultClass \Drupal\Component\Utility\SafeMarkup
  */
 class SafeMarkupTest extends TestCase {
@@ -35,6 +36,7 @@ protected function tearDown() {
    * Tests SafeMarkup::isSafe() with different objects.
    *
    * @covers ::isSafe
+   * @expectedDeprecation SafeMarkup::isSafe() is scheduled for removal in Drupal 9.0.0. Instead, you should just check if a variable is an instance of \Drupal\Component\Render\MarkupInterface. See https://www.drupal.org/node/2549395.
    */
   public function testIsSafe() {
     $safe_string = $this->getMockBuilder('\Drupal\Component\Render\MarkupInterface')->getMock();
@@ -48,6 +50,7 @@ public function testIsSafe() {
    *
    * @dataProvider providerCheckPlain
    * @covers ::checkPlain
+   * @expectedDeprecation SafeMarkup::checkPlain() is scheduled for removal in Drupal 9.0.0. Rely on Twig's auto-escaping feature, or use the @link theme_render #plain_text @endlink key when constructing a render array that contains plain text in order to use the renderer's auto-escaping feature. If neither of these are possible, \Drupal\Component\Utility\Html::escape() can be used in places where explicit escaping is needed. See https://www.drupal.org/node/2549395.
    *
    * @param string $text
    *   The text to provide to SafeMarkup::checkPlain().
@@ -125,10 +128,6 @@ public function testFormat($string, array $args, $expected, $message, $expected_
     $result = SafeMarkup::format($string, $args);
     $this->assertEquals($expected, (string) $result, $message);
     $this->assertEquals($expected_is_safe, $result instanceof MarkupInterface, 'SafeMarkup::format correctly sets the result as safe or not safe.');
-
-    foreach ($args as $arg) {
-      $this->assertSame($arg instanceof SafeMarkupTestMarkup, SafeMarkup::isSafe($arg));
-    }
   }
 
   /**
diff --git a/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionTest.php b/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionTest.php
index 6eda2e3646a08b9f6b9d0ead8747d7043a76015d..e6ad236a7226d61ca2cd55f87161db8c76593e02 100644
--- a/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionTest.php
+++ b/core/tests/Drupal/Tests/Core/Plugin/Context/ContextDefinitionTest.php
@@ -110,7 +110,6 @@ public function testGetDataDefinition($is_multiple) {
    * @dataProvider providerGetDataDefinition
    * @covers ::getDataDefinition
    * @uses \Drupal
-   * @uses \Drupal\Component\Utility\SafeMarkup
    */
   public function testGetDataDefinitionInvalidType($is_multiple) {
     // Since we're trying to make getDataDefinition() throw an exception in