diff --git a/core/core.services.yml b/core/core.services.yml
index c4c7593..66b2797 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -197,7 +197,7 @@ services:
     arguments: ['@request_stack', '@string_translation', '@csrf_token', '@logger.channel.form']
   form_submitter:
     class: Drupal\Core\Form\FormSubmitter
-    arguments: ['@request_stack', '@url_generator']
+    arguments: ['@request_stack', '@url_generator', '@current_route_match']
   form_cache:
     class: Drupal\Core\Form\FormCache
     arguments: ['@app.root', '@keyvalue.expirable', '@module_handler', '@current_user', '@csrf_token', '@logger.channel.form', '@config.factory', '@request_stack', '@page_cache_request_policy']
diff --git a/core/lib/Drupal/Core/Form/FormSubmitter.php b/core/lib/Drupal/Core/Form/FormSubmitter.php
index b975a70..f4c4812 100644
--- a/core/lib/Drupal/Core/Form/FormSubmitter.php
+++ b/core/lib/Drupal/Core/Form/FormSubmitter.php
@@ -12,6 +12,7 @@
 use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\HttpFoundation\Response;
 use Drupal\Core\Routing\UrlGeneratorInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 
 /**
  * Provides submission processing for forms.
@@ -33,15 +34,25 @@ class FormSubmitter implements FormSubmitterInterface {
   protected $requestStack;
 
   /**
+   * The current route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $currentRouteMatch;
+
+  /**
    * Constructs a new FormValidator.
    *
    * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
    *   The request stack.
    * @param \Drupal\Core\Routing\UrlGeneratorInterface $url_generator
+   * @param \Drupal\Core\Routing\RouteMatchInterface $current_route_match
    */
-  public function __construct(RequestStack $request_stack, UrlGeneratorInterface $url_generator) {
+  public function __construct(RequestStack $request_stack, UrlGeneratorInterface
+      $url_generator, RouteMatchInterface $current_route_match) {
     $this->requestStack = $request_stack;
     $this->urlGenerator = $url_generator;
+    $this->currentRouteMatch = $current_route_match;
   }
 
   /**
@@ -137,12 +148,15 @@ 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(
+        $this->currentRouteMatch->getRouteName(),
+        $this->currentRouteMatch->getRawParameters()->all(),
+        array(
+          '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 9167501..2c53cce 100644
--- a/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
+++ b/core/modules/system/src/Tests/Form/ElementsTableSelectTest.php
@@ -195,7 +195,6 @@ function testMultipleFalseOptionchecker() {
     $this->assertTrue(isset($errors['tableselect']), 'Option checker disallows invalid values for radio buttons.');
   }
 
-
   /**
    * Helper function for the option check test to submit a form while collecting errors.
    *
@@ -215,15 +214,16 @@ private function formSubmitHelper($form, $edit) {
     // The form token CSRF protection should not interfere with this test, so we
     // bypass it by setting the token to FALSE.
     $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));
-
     \Drupal::formBuilder()->prepareForm($form_id, $form, $form_state);
-
     \Drupal::formBuilder()->processForm($form_id, $form, $form_state);
-
     $errors = $form_state->getErrors();
 
     // Clear errors and messages.
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..56c0ef7 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,8 @@
 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..4b7715e 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormSubmitterTest.php
@@ -14,6 +14,7 @@
 use Symfony\Component\HttpFoundation\RedirectResponse;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Component\HttpFoundation\RequestStack;
+use Symfony\Component\HttpFoundation\ParameterBag;
 
 /**
  * @coversDefaultClass \Drupal\Core\Form\FormSubmitter
@@ -29,11 +30,19 @@ class FormSubmitterTest extends UnitTestCase {
   protected $urlGenerator;
 
   /**
+   * The mocked URL generator.
+   *
+   * @var \PHPUnit_Framework_MockObject_MockObject|\Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
    * {@inheritdoc}
    */
   protected function setUp() {
     parent::setUp();
     $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
+    $this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
   }
 
   /**
@@ -103,14 +112,22 @@ public function providerTestHandleFormSubmissionWithResponses() {
   public function testRedirectWithNull() {
     $form_submitter = $this->getFormSubmitter();
     $this->urlGenerator->expects($this->once())
-      ->method('generateFromPath')
-      ->with(NULL, array('query' => array(), 'absolute' => TRUE))
+      ->method('generateFromRoute')
+      ->with('<front>', [], array('query' => array(), 'absolute' => TRUE))
+      ->willReturn('<front>');
+
+    $this->routeMatch->expects($this->once())
+      ->method('getRouteName')
       ->willReturn('<front>');
+    $this->routeMatch->expects($this->once())
+      ->method('getRawParameters')
+      ->willReturn(new ParameterBag());
 
     $form_state = $this->getMock('Drupal\Core\Form\FormStateInterface');
     $form_state->expects($this->once())
       ->method('getRedirect')
       ->willReturn(NULL);
+
     $redirect = $form_submitter->redirectForm($form_state);
     $this->assertSame('<front>', $redirect->getTargetUrl());
     $this->assertSame(303, $redirect->getStatusCode());
@@ -236,7 +253,7 @@ protected function getFormSubmitter() {
     $request_stack = new RequestStack();
     $request_stack->push(new Request());
     return $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
-      ->setConstructorArgs(array($request_stack, $this->urlGenerator))
+      ->setConstructorArgs(array($request_stack, $this->urlGenerator, $this->routeMatch))
       ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
       ->getMock();
   }
diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
index 2386eb2..54f6a92 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
@@ -138,6 +138,7 @@ protected function setUp() {
 
     $this->formCache = $this->getMock('Drupal\Core\Form\FormCacheInterface');
     $this->urlGenerator = $this->getMock('Drupal\Core\Routing\UrlGeneratorInterface');
+    $this->routeMatch = $this->getMock('Drupal\Core\Routing\RouteMatchInterface');
     $this->classResolver = $this->getClassResolverStub();
     $this->csrfToken = $this->getMockBuilder('Drupal\Core\Access\CsrfTokenGenerator')
       ->disableOriginalConstructor()
@@ -157,7 +158,7 @@ protected function setUp() {
       ->setMethods(array('drupalSetMessage'))
       ->getMock();
     $this->formSubmitter = $this->getMockBuilder('Drupal\Core\Form\FormSubmitter')
-      ->setConstructorArgs(array($this->requestStack, $this->urlGenerator))
+      ->setConstructorArgs(array($this->requestStack, $this->urlGenerator, $this->routeMatch))
       ->setMethods(array('batchGet', 'drupalInstallationAttempted'))
       ->getMock();
     $this->root = dirname(dirname(substr(__DIR__, 0, -strlen(__NAMESPACE__))));
