diff --git a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
index c393a34..0422bf0 100644
--- a/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/CustomPageExceptionHtmlSubscriber.php
@@ -63,7 +63,7 @@ protected static function getPriority() {
    */
   public function on403(GetResponseForExceptionEvent $event) {
     $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.403'));
-    $this->makeSubrequest($event, $path, Response::HTTP_FORBIDDEN);
+    $this->makeSubrequest($event, $event->getRequest()->getBasePath() . '/' . $path, Response::HTTP_FORBIDDEN);
   }
 
   /**
@@ -71,7 +71,7 @@ public function on403(GetResponseForExceptionEvent $event) {
    */
   public function on404(GetResponseForExceptionEvent $event) {
     $path = $this->aliasManager->getPathByAlias($this->configFactory->get('system.site')->get('page.404'));
-    $this->makeSubrequest($event, $path, Response::HTTP_NOT_FOUND);
+    $this->makeSubrequest($event, $event->getRequest()->getBasePath() . '/' . $path, Response::HTTP_NOT_FOUND);
   }
 
 }
diff --git a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
index 9535abf..d6782b2 100644
--- a/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/DefaultExceptionHtmlSubscriber.php
@@ -7,6 +7,7 @@
 
 namespace Drupal\Core\EventSubscriber;
 
+use Drupal\Core\Url;
 use Drupal\Core\Utility\Error;
 use Psr\Log\LoggerInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -69,7 +70,7 @@ protected function getHandledFormats() {
    *   The event to process.
    */
   public function on403(GetResponseForExceptionEvent $event) {
-    $this->makeSubrequest($event, 'system/403', Response::HTTP_FORBIDDEN);
+    $this->makeSubrequest($event, Url::fromRoute('system.403')->toString(), Response::HTTP_FORBIDDEN);
   }
 
   /**
@@ -79,7 +80,7 @@ public function on403(GetResponseForExceptionEvent $event) {
    *   The event to process.
    */
   public function on404(GetResponseForExceptionEvent $event) {
-    $this->makeSubrequest($event, 'system/404', Response::HTTP_NOT_FOUND);
+    $this->makeSubrequest($event, Url::fromRoute('system.404')->toString(), Response::HTTP_NOT_FOUND);
   }
 
   /**
@@ -87,24 +88,22 @@ public function on404(GetResponseForExceptionEvent $event) {
    *
    * @param \Symfony\Component\HttpKernel\Event\GetResponseForExceptionEvent $event
    *   The event to process
-   * @param string $path
-   *   The path to which to make a subrequest for this error message.
+   * @param string $url
+   *   The url to which to make a subrequest for this error message.
    * @param int $status_code
    *   The status code for the error being handled.
    */
-  protected function makeSubrequest(GetResponseForExceptionEvent $event, $path, $status_code) {
+  protected function makeSubrequest(GetResponseForExceptionEvent $event, $url, $status_code) {
     $request = $event->getRequest();
 
-    // @todo Remove dependency on the internal _system_path attribute:
-    //   https://www.drupal.org/node/2293523.
-    $system_path = $request->attributes->get('_system_path');
+    $current_url = $request->getBasePath() . $request->getPathInfo();
 
-    if ($path && $path != $system_path) {
+    if ($url != $request->getBasePath() . '/' && $url != $current_url) {
       if ($request->getMethod() === 'POST') {
-        $sub_request = Request::create($request->getBaseUrl() . '/' . $path, 'POST', ['destination' => $system_path, '_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all());
+        $sub_request = Request::create($url, 'POST', drupal_get_destination() + ['_exception_statuscode' => $status_code] + $request->request->all(), $request->cookies->all(), [], $request->server->all());
       }
       else {
-        $sub_request = Request::create($request->getBaseUrl() . '/' . $path, 'GET', $request->query->all() + ['destination' => $system_path, '_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all());
+        $sub_request = Request::create($url, 'GET', $request->query->all() + drupal_get_destination() + ['_exception_statuscode' => $status_code], $request->cookies->all(), [], $request->server->all());
       }
 
       try {
diff --git a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
index 3d42176..eba6e7c 100644
--- a/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
+++ b/core/lib/Drupal/Core/EventSubscriber/ExceptionLoggingSubscriber.php
@@ -45,9 +45,7 @@ public function __construct(LoggerChannelFactoryInterface $logger) {
    */
   public function on403(GetResponseForExceptionEvent $event) {
     $request = $event->getRequest();
-    // @todo Remove dependency on the internal _system_path attribute:
-    //   https://www.drupal.org/node/2293523.
-    $this->logger->get('access denied')->warning(String::checkPlain($request->attributes->get('_system_path')));
+    $this->logger->get('access denied')->warning(String::checkPlain($request->getRequestUri()));
   }
 
   /**
@@ -58,9 +56,7 @@ public function on403(GetResponseForExceptionEvent $event) {
    */
   public function on404(GetResponseForExceptionEvent $event) {
     $request = $event->getRequest();
-    // @todo Remove dependency on the internal _system_path attribute:
-    //   https://www.drupal.org/node/2293523.
-    $this->logger->get('page not found')->warning(String::checkPlain($request->attributes->get('_system_path')));
+    $this->logger->get('page not found')->warning(String::checkPlain($request->getRequestUri()));
   }
 
   /**
diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php
index f2c888d..a9bd0ac 100644
--- a/core/lib/Drupal/Core/Form/FormSubmitter.php
+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -137,12 +137,7 @@ public function redirectForm(FormStateInterface $form_state) {
     // If no redirect was specified, redirect to the current path.
     elseif ($redirect === NULL) {
       $request = $this->requestStack->getCurrentRequest();
-      // @todo Remove dependency on the internal _system_path attribute:
-      //   https://www.drupal.org/node/2293521.
-      $url = $this->urlGenerator->generateFromPath($request->attributes->get('_system_path'), array(
-        'query' => $request->query->all(),
-        'absolute' => TRUE,
-      ));
+      $url = $this->urlGenerator->generateFromRoute('<current>', [], ['query' => $request->query->all(), 'absolute' => TRUE]);
     }
 
     if ($url) {
diff --git a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
index a80e50f..7265769 100644
--- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
+++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
@@ -217,6 +217,11 @@ private function formSubmitHelper($form, $edit) {
     $form['#token'] = FALSE;
 
     $edit['form_id'] = $form_id;
+
+    // Disable page redirect for forms submitted programmatically. This is a
+    // solution to skip redirect step (there are no pages, then the redirect
+    // isn't possible).
+    $form_state->disableRedirect();
     $form_state->setUserInput($edit);
     $form_state->setFormObject(new StubForm($form_id, $form));
 
diff --git a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
index b4e4393..01fa88f 100644
--- a/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
+++ b/core/modules/system/tests/modules/theme_test/src/EventSubscriber/ThemeTestSubscriber.php
@@ -8,6 +8,7 @@
 namespace Drupal\theme_test\EventSubscriber;
 
 use Drupal\Core\Url;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\HttpKernel\KernelEvents;
 use Symfony\Component\HttpKernel\Event\GetResponseEvent;
 use Symfony\Component\EventDispatcher\EventSubscriberInterface;
@@ -24,6 +25,22 @@ class ThemeTestSubscriber implements EventSubscriberInterface {
    */
   protected $container;
 
+  /**
+   * The current route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $currentRouteMatch;
+
+  /**
+   * Constructs a new ThemeTestSubscriber.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
+   */
+  public function __construct(RouteMatchInterface $current_route_match) {
+    $this->currentRouteMatch = $current_route_match;
+  }
+
 
   /**
    * Generates themed output early in a page request.
@@ -31,9 +48,7 @@ class ThemeTestSubscriber implements EventSubscriberInterface {
    * @see \Drupal\system\Tests\Theme\ThemeEarlyInitializationTest::testRequestListener()
    */
   public function onRequest(GetResponseEvent $event) {
-    $request = $event->getRequest();
-    $current_path = $request->attributes->get('_system_path');
-    if ($current_path == 'theme-test/request-listener') {
+    if ($this->currentRouteMatch->getRouteName() === 'theme_test.request_listener') {
       // First, force the theme registry to be rebuilt on this page request.
       // This allows us to test a full initialization of the theme system in
       // the code below.
@@ -56,9 +71,13 @@ public function onRequest(GetResponseEvent $event) {
    * Ensures that the theme registry was not initialized.
    */
   public function onView(GetResponseEvent $event) {
-    $request = $event->getRequest();
-    $current_path = $request->attributes->get('_system_path');
-    if (strpos($current_path, 'user/autocomplete') === 0) {
+    $current_route = $this->currentRouteMatch->getRouteName();
+    $user_autcomplete_route = array(
+      'user.autocomplete',
+      'user.autocomplete_anonymous',
+    );
+
+    if (in_array($current_route, $user_autcomplete_route)) {
       if ($this->container->initialized('theme.registry')) {
         throw new \Exception('registry initialized');
       }
diff --git a/core/modules/system/tests/modules/theme_test/theme_test.services.yml b/core/modules/system/tests/modules/theme_test/theme_test.services.yml
index 69fd3ca..add8b4c 100644
--- a/core/modules/system/tests/modules/theme_test/theme_test.services.yml
+++ b/core/modules/system/tests/modules/theme_test/theme_test.services.yml
@@ -1,6 +1,7 @@
 services:
   theme_test.subscriber:
     class: Drupal\theme_test\EventSubscriber\ThemeTestSubscriber
+    arguments: [@current_route_match]
     tags:
       - { name: event_subscriber }
 
diff --git a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
index ff2b2cd..4e7e85c 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
@@ -102,17 +102,20 @@ public function providerTestHandleFormSubmissionWithResponses() {
    */
   public function testRedirectWithNull() {
     $form_submitter = $this->getFormSubmitter();
-    $this->urlGenerator->expects($this->once())
-      ->method('generateFromPath')
-      ->with(NULL, array('query' => array(), 'absolute' => TRUE))
-      ->willReturn('<front>');
 
     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
     $form_state->expects($this->once())
       ->method('getRedirect')
       ->willReturn(NULL);
+
+    $this->urlGenerator->expects($this->once())
+      ->method('generateFromRoute')
+      ->with('<current>', [], ['query' => [], 'absolute' => TRUE])
+      ->willReturn('http://localhost/test-path');
+
     $redirect = $form_submitter->redirectForm($form_state);
-    $this->assertSame('<front>', $redirect->getTargetUrl());
+    // If we have no redirect, we redirect to the current URL.
+    $this->assertSame('http://localhost/test-path', $redirect->getTargetUrl());
     $this->assertSame(303, $redirect->getStatusCode());
   }
 
@@ -234,7 +237,7 @@ public function testExecuteSubmitHandlers() {
    */
   protected function getFormSubmitter() {
     $request_stack = new RequestStack();
-    $request_stack->push(new Request());
+    $request_stack->push(Request::create('/test-path'));
     return $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
       ->setConstructorArgs(array($request_stack, $this->urlGenerator))
       ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
