diff --git a/core/lib/Drupal/Core/Url.php b/core/lib/Drupal/Core/Url.php
index 2fd8aca..90d43c2 100644
--- a/core/lib/Drupal/Core/Url.php
+++ b/core/lib/Drupal/Core/Url.php
@@ -740,13 +740,6 @@ public function toString() {
   }
 
   /**
-   * {@inheritdoc}
-   */
-  public function __toString() {
-    return $this->toString();
-  }
-
-  /**
    * Returns the route information for a render array.
    *
    * @return array
diff --git a/core/modules/forum/src/Tests/ForumTest.php b/core/modules/forum/src/Tests/ForumTest.php
index 6feb754..ab53984 100644
--- a/core/modules/forum/src/Tests/ForumTest.php
+++ b/core/modules/forum/src/Tests/ForumTest.php
@@ -117,7 +117,7 @@ function testForum() {
     //Check that the basic forum install creates a default forum topic
     $this->drupalGet('/forum');
     // Look for the "General discussion" default forum
-    $this->assertRaw(t('<a href="'. Url::fromRoute('forum.page', ['taxonomy_term' => 1]) .'">General discussion</a>'), "Found the default forum at the /forum listing");
+    $this->assertRaw(t('<a href="'. Url::fromRoute('forum.page', ['taxonomy_term' => 1])->toString() .'">General discussion</a>'), "Found the default forum at the /forum listing");
 
     // Do the admin tests.
     $this->doAdminTests($this->admin_user);
diff --git a/core/modules/locale/src/Tests/LocaleConfigTranslationImportTest.php b/core/modules/locale/src/Tests/LocaleConfigTranslationImportTest.php
index cacf88d..a0a8684 100644
--- a/core/modules/locale/src/Tests/LocaleConfigTranslationImportTest.php
+++ b/core/modules/locale/src/Tests/LocaleConfigTranslationImportTest.php
@@ -36,7 +36,7 @@ protected function setUp() {
 
     // Update module should not go out to d.o to check for updates. We override
     // the url to an invalid update source. No update data will be found.
-    $this->config('update.settings')->set('fetch.url', (string) Url::fromRoute('<front>', array(), array('absolute' => TRUE)))->save();
+    $this->config('update.settings')->set('fetch.url', (string) Url::fromRoute('<front>')->setAbsolute()->toString())->save();
   }
 
   /**
diff --git a/core/modules/node/src/Tests/NodeTranslationUITest.php b/core/modules/node/src/Tests/NodeTranslationUITest.php
index df9cbe7..855d961 100644
--- a/core/modules/node/src/Tests/NodeTranslationUITest.php
+++ b/core/modules/node/src/Tests/NodeTranslationUITest.php
@@ -340,7 +340,7 @@ protected function doTestAlternateHreflangLinks(Url $url) {
         // Retrieve desired link elements from the HTML head.
         $links = $this->xpath('head/link[@rel = "alternate" and @href = :href and @hreflang = :hreflang]',
           array(':href' => $language_url->toString(), ':hreflang' => $alternate_langcode));
-        $this->assert(isset($links[0]), format_string('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', array('%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url)));
+        $this->assert(isset($links[0]), format_string('The %langcode node translation has the correct alternate hreflang link for %alternate_langcode: %link.', array('%langcode' => $langcode, '%alternate_langcode' => $alternate_langcode, '%link' => $url->toString())));
       }
     }
   }
diff --git a/core/modules/simpletest/src/WebTestBase.php b/core/modules/simpletest/src/WebTestBase.php
index e27b690..a691906 100644
--- a/core/modules/simpletest/src/WebTestBase.php
+++ b/core/modules/simpletest/src/WebTestBase.php
@@ -1505,6 +1505,10 @@ protected function drupalGet($path, array $options = array(), array $headers = a
       $out = $new;
     }
 
+    if ($path instanceof Url) {
+      $path = $path->toString();
+    }
+
     $verbose = 'GET request to: ' . $path .
                '<hr />Ending URL: ' . $this->getUrl();
     if ($this->dumpHeaders) {
@@ -1696,6 +1700,9 @@ protected function drupalPostForm($path, $edit, $submit, array $options = array(
             $out = $new;
           }
 
+          if ($path instanceof Url) {
+            $path = $path->toString();
+          }
           $verbose = 'POST request to: ' . $path;
           $verbose .= '<hr />Ending URL: ' . $this->getUrl();
           if ($this->dumpHeaders) {
diff --git a/core/modules/system/src/Tests/Theme/EngineTwigTest.php b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
index c154b43..750ae2e 100644
--- a/core/modules/system/src/Tests/Theme/EngineTwigTest.php
+++ b/core/modules/system/src/Tests/Theme/EngineTwigTest.php
@@ -84,7 +84,26 @@ public function testTwigLinkGenerator() {
   }
 
   /**
-   * Tests the file_url Twig functions.
+   * Tests the magic url to string Twig functions.
+   *
+   * @see \Drupal\Core\Url
+   */
+  public function testTwigUrlToString() {
+    $this->drupalGet('twig-theme-test/url-to-string');
+
+    $expected = [
+      'rendered url: ' . Url::fromRoute('user.register')->toString(),
+    ];
+
+    $content = $this->getRawContent();
+    $this->assertFalse(empty($content), 'Page content is not empty');
+    foreach ($expected as $string) {
+      $this->assertRaw('<div>' . $string . '</div>');
+    }
+  }
+
+  /**
+   * Tests the automatic/magic calling of toString() on objects, if exists.
    */
   public function testTwigFileUrls() {
     $this->drupalGet('/twig-theme-test/file-url');
diff --git a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
index 2bf5394..ff49bd6 100644
--- a/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
+++ b/core/modules/system/tests/modules/twig_theme_test/src/TwigThemeTestController.php
@@ -50,6 +50,16 @@ public function linkGeneratorRender() {
   }
 
   /**
+   * Renders a URL to a string.
+   */
+  public function urlToStringRender() {
+    return [
+      '#theme' => 'twig_theme_test_url_to_string',
+      '#test_url' => Url::fromRoute('user.register'),
+    ];
+  }
+
+  /**
    * Renders for testing file_url functions in a Twig template.
    */
   public function fileUrlRender() {
diff --git a/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_to_string.html.twig b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_to_string.html.twig
new file mode 100644
index 0000000..e337a6f
--- /dev/null
+++ b/core/modules/system/tests/modules/twig_theme_test/templates/twig_theme_test.url_to_string.html.twig
@@ -0,0 +1 @@
+<div>rendered url: {{ test_url }}</div>
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
index e42b020..7f6fe35 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.module
@@ -42,6 +42,10 @@ function twig_theme_test_theme($existing, $type, $theme, $path) {
     'variables' => array('test_url' => NULL),
     'template' => 'twig_theme_test.link_generator',
   );
+  $items['twig_theme_test_url_to_string'] = array(
+    'variables' => array('test_url' => NULL),
+    'template' => 'twig_theme_test.url_to_string',
+  );
   $items['twig_theme_test_file_url'] = array(
     'variables' => array(),
     'template' => 'twig_theme_test.file_url',
diff --git a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
index 4d30bb9..1001b47 100644
--- a/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
+++ b/core/modules/system/tests/modules/twig_theme_test/twig_theme_test.routing.yml
@@ -26,6 +26,13 @@ twig_theme_test_link_generator:
   requirements:
     _access: 'TRUE'
 
+twig_theme_test_url_to_string:
+  path: '/twig-theme-test/url-to-string'
+  defaults:
+    _controller: '\Drupal\twig_theme_test\TwigThemeTestController::urlToStringRender'
+  requirements:
+    _access: 'TRUE'
+
 twig_theme_test_file_url:
   path: '/twig-theme-test/file-url'
   defaults:
diff --git a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
index 28cdcd1..fcf4904 100644
--- a/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
+++ b/core/modules/views/src/Plugin/views/field/FieldPluginBase.php
@@ -715,7 +715,7 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
         '#title' => $this->t('Text'),
         '#type' => 'textarea',
         '#default_value' => $this->options['alter']['text'],
-        '#description' => $this->t('The text to display for this field. You may include HTML or <a href="@url">Twig</a>. You may enter data from this view as per the "Replacement patterns" below.', array('@url' => CoreUrl::fromUri('http://twig.sensiolabs.org/documentation'))),
+        '#description' => $this->t('The text to display for this field. You may include HTML or <a href="@url">Twig</a>. You may enter data from this view as per the "Replacement patterns" below.', array('@url' => CoreUrl::fromUri('http://twig.sensiolabs.org/documentation')->toString())),
         '#states' => array(
           'visible' => array(
             ':input[name="options[alter][alter_text]"]' => array('checked' => TRUE),
diff --git a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php b/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
index 219ebda..8ce1f9b 100644
--- a/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
+++ b/core/modules/views/src/Tests/Handler/FieldEntityOperationsTest.php
@@ -50,7 +50,7 @@ public function testEntityOperations() {
     foreach ($entities as $entity) {
       $operations = \Drupal::entityManager()->getListBuilder('entity_test')->getOperations($entity);
       foreach ($operations as $operation) {
-        $expected_destination = Url::fromUri('internal:/test-entity-operations');
+        $expected_destination = Url::fromUri('internal:/test-entity-operations')->toString();
         $result = $this->xpath('//ul[contains(@class, dropbutton)]/li/a[contains(@href, :path) and text()=:title]', array(':path' => $operation['url'] . '?destination=' . $expected_destination, ':title' => $operation['title']));
         $this->assertEqual(count($result), 1, t('Found entity @operation link with destination parameter.', array('@operation' => $operation['title'])));
       }
diff --git a/core/modules/views_ui/src/ViewUI.php b/core/modules/views_ui/src/ViewUI.php
index 1d3c8be..857d7c9 100644
--- a/core/modules/views_ui/src/ViewUI.php
+++ b/core/modules/views_ui/src/ViewUI.php
@@ -726,7 +726,7 @@ public function renderPreview($display_id, $args = array()) {
             if (isset($path)) {
               // @todo Views should expect and store a leading /. See:
               //   https://www.drupal.org/node/2423913
-              $path = \Drupal::l($path, Url::fromUserInput('/' . $path));
+              $path = \Drupal::l($path->toString(), Url::fromUserInput('/' . $path));
             }
             else {
               $path = t('This display has no path.');
diff --git a/core/tests/Drupal/Tests/Core/UrlTest.php b/core/tests/Drupal/Tests/Core/UrlTest.php
index 98c8f36..dcc2c66 100644
--- a/core/tests/Drupal/Tests/Core/UrlTest.php
+++ b/core/tests/Drupal/Tests/Core/UrlTest.php
@@ -376,24 +376,6 @@ public function testToString($urls) {
   }
 
   /**
-   * Tests the __toString() method.
-   *
-   * @param \Drupal\Core\Url[] $urls
-   *   An array of Url objects.
-   *
-   * @depends testUrlFromRequest
-   *
-   * @covers ::__toString
-   */
-  public function testMagicToString($urls) {
-    foreach ($urls as $index => $url) {
-      $url->setUrlGenerator(\Drupal::urlGenerator());
-      $path = array_pop($this->map[$index]);
-      $this->assertSame($path, (string) $url);
-    }
-  }
-
-  /**
    * Tests the getRouteName() method.
    *
    * @param \Drupal\Core\Url[] $urls
diff --git a/core/themes/engines/twig/twig.engine b/core/themes/engines/twig/twig.engine
index 39e866a..414ca2c 100644
--- a/core/themes/engines/twig/twig.engine
+++ b/core/themes/engines/twig/twig.engine
@@ -150,6 +150,12 @@ function twig_render_var($arg) {
     if (method_exists($arg, '__toString')) {
       return (string) $arg;
     }
+    // You can't throw exceptions in the magic PHP __toString methods, see
+    // http://php.net/manual/en/language.oop5.magic.php#object.tostring so
+    // we also support a toString method.
+    elseif (method_exists($arg, 'toString')) {
+      return $arg->toString();
+    }
     else {
       throw new Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($arg))));
     }
@@ -237,6 +243,12 @@ function twig_drupal_escape_filter(\Twig_Environment $env, $string, $strategy =
     if (method_exists($string, '__toString')) {
       $return = (string) $string;
     }
+    // You can't throw exceptions in the magic PHP __toString methods, see
+    // http://php.net/manual/en/language.oop5.magic.php#object.tostring so
+    // we also support a toString method.
+    elseif (method_exists($string, 'toString')) {
+      $return = $string->toString();
+    }
     else {
       throw new \Exception(t('Object of type "@class" cannot be printed.', array('@class' => get_class($string))));
     }
