diff --git a/core/core.services.yml b/core/core.services.yml
index 9ab7af7e022caef504adb7e036c6c54734e34d1f..8a5a126e5440a3ffcde8260141a6753c55efe42e 100644
--- a/core/core.services.yml
+++ b/core/core.services.yml
@@ -505,7 +505,7 @@ services:
       - [fromRequestStack, ['@request_stack']]
   router.admin_context:
     class: Drupal\Core\Routing\AdminContext
-    arguments: ['@request_stack']
+    arguments: ['@current_route_match']
   router.route_provider:
     class: Drupal\Core\Routing\RouteProvider
     arguments: ['@database', '@router.builder', '@state']
diff --git a/core/lib/Drupal/Core/Controller/ControllerResolver.php b/core/lib/Drupal/Core/Controller/ControllerResolver.php
index d5193e76541fbc07b964e90b93ed0e023bd5b42a..febffd906ed3b6b7dab8ec621bf21686b03d1b61 100644
--- a/core/lib/Drupal/Core/Controller/ControllerResolver.php
+++ b/core/lib/Drupal/Core/Controller/ControllerResolver.php
@@ -138,11 +138,15 @@ protected function createController($controller) {
    */
   protected function doGetArguments(Request $request, $controller, array $parameters) {
     $attributes = $request->attributes->all();
+    $raw_parameters = $request->attributes->has('_raw_variables') ? $request->attributes->get('_raw_variables') : [];
     $arguments = array();
     foreach ($parameters as $param) {
       if (array_key_exists($param->name, $attributes)) {
         $arguments[] = $attributes[$param->name];
       }
+      elseif (array_key_exists($param->name, $raw_parameters)) {
+        $arguments[] = $attributes[$param->name];
+      }
       elseif ($param->getClass() && $param->getClass()->isInstance($request)) {
         $arguments[] = $request;
       }
@@ -166,21 +170,6 @@ protected function doGetArguments(Request $request, $controller, array $paramete
         throw new \RuntimeException(sprintf('Controller "%s" requires that you provide a value for the "$%s" argument (because there is no default value or because there is a non optional argument after this one).', $repr, $param->name));
       }
     }
-
-    // The parameter converter overrides the raw request attributes with the
-    // upcasted objects. However, it keeps a backup copy of the original, raw
-    // values in a special request attribute ('_raw_variables'). If a controller
-    // argument has a type hint, we pass it the upcasted object, otherwise we
-    // pass it the original, raw value.
-    if ($request->attributes->has('_raw_variables') && $raw = $request->attributes->get('_raw_variables')->all()) {
-      foreach ($parameters as $parameter) {
-        // Use the raw value if a parameter has no typehint.
-        if (!$parameter->getClass() && isset($raw[$parameter->name])) {
-          $position = $parameter->getPosition();
-          $arguments[$position] = $raw[$parameter->name];
-        }
-      }
-    }
     return $arguments;
   }
 
diff --git a/core/lib/Drupal/Core/Form/FormBase.php b/core/lib/Drupal/Core/Form/FormBase.php
index 3a146127930b622c497479af7a4fbc0275579809..b60e9ed32cc6702caedcb6b77a15561f4a533d68 100644
--- a/core/lib/Drupal/Core/Form/FormBase.php
+++ b/core/lib/Drupal/Core/Form/FormBase.php
@@ -53,6 +53,13 @@ abstract class FormBase implements FormInterface, ContainerInjectionInterface {
    */
   protected $loggerFactory;
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
   /**
    * {@inheritdoc}
    */
@@ -135,6 +142,18 @@ protected function getRequest() {
     return $this->requestStack->getCurrentRequest();
   }
 
+  /**
+   * Gets the route match.
+   *
+   * @return \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected function getRouteMatch() {
+    if (!$this->routeMatch) {
+      $this->routeMatch = \Drupal::routeMatch();
+    }
+    return $this->routeMatch;
+  }
+
   /**
    * Sets the request stack object to use.
    *
diff --git a/core/lib/Drupal/Core/Routing/AdminContext.php b/core/lib/Drupal/Core/Routing/AdminContext.php
index dac583915522878b591cdb4e2fbfe126a28ba82e..5ea7c9cce51e2c168950c8dd7784808d123f7b02 100644
--- a/core/lib/Drupal/Core/Routing/AdminContext.php
+++ b/core/lib/Drupal/Core/Routing/AdminContext.php
@@ -7,8 +7,6 @@
 
 namespace Drupal\Core\Routing;
 
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
-use Symfony\Component\HttpFoundation\RequestStack;
 use Symfony\Component\Routing\Route;
 
 /**
@@ -17,20 +15,20 @@
 class AdminContext {
 
   /**
-   * The request stack
+   * The route match.
    *
-   * @var \Symfony\Component\HttpFoundation\RequestStack
+   * @var \Drupal\Core\Routing\RouteMatchInterface
    */
-  protected $requestStack;
+  protected $routeMatch;
 
   /**
    * Construct a new admin context helper instance.
    *
-   * @param \Symfony\Component\HttpFoundation\RequestStack $request_stack
-   *   The request stack used to determine the current request.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
    */
-  public function __construct(RequestStack $request_stack) {
-    $this->requestStack = $request_stack;
+  public function __construct(RouteMatchInterface $route_match) {
+    $this->routeMatch = $route_match;
   }
 
   /**
@@ -45,7 +43,7 @@ public function __construct(RequestStack $request_stack) {
    */
   public function isAdminRoute(Route $route = NULL) {
     if (!$route) {
-      $route = $this->getRouteFromRequest();
+      $route = $this->routeMatch->getRouteObject();
       if (!$route) {
         return FALSE;
       }
@@ -53,17 +51,4 @@ public function isAdminRoute(Route $route = NULL) {
     return (bool) $route->getOption('_admin_route');
   }
 
-  /**
-   * Extract the route object from the request if one is available.
-   *
-   * @return \Symfony\Component\Routing\Route
-   *   The route object extracted from the current request.
-   */
-  protected function getRouteFromRequest() {
-    $request = $this->requestStack->getCurrentRequest();
-    if ($request) {
-      return $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT);
-    }
-  }
-
 }
diff --git a/core/lib/Drupal/Core/Routing/CurrentRouteMatch.php b/core/lib/Drupal/Core/Routing/CurrentRouteMatch.php
index 4b482eaf6b6ae729b0be4ddf5331432d8b3dd466..979c1891d0fb105e0aa921e5a8944f89d1f49202 100644
--- a/core/lib/Drupal/Core/Routing/CurrentRouteMatch.php
+++ b/core/lib/Drupal/Core/Routing/CurrentRouteMatch.php
@@ -132,4 +132,11 @@ public function getParentRouteMatch() {
     return $this->getRouteMatch($this->requestStack->getParentRequest());
   }
 
+  /**
+   * {@inheritdoc}
+   */
+  public function getRouteMatchFromRequest(Request $request) {
+    return $this->getRouteMatch($request);
+  }
+
 }
diff --git a/core/lib/Drupal/Core/Routing/StackedRouteMatchInterface.php b/core/lib/Drupal/Core/Routing/StackedRouteMatchInterface.php
index fde003596ad9c1552ec11f9e83d5b5f4bda7aaac..e5eb809290675e8d16ddc8448f51ed05bdb1acc7 100644
--- a/core/lib/Drupal/Core/Routing/StackedRouteMatchInterface.php
+++ b/core/lib/Drupal/Core/Routing/StackedRouteMatchInterface.php
@@ -7,6 +7,8 @@
 
 namespace Drupal\Core\Routing;
 
+use Symfony\Component\HttpFoundation\Request;
+
 /**
  * Defines an interface for a stack of route matches.
  *
@@ -36,5 +38,15 @@ public function getMasterRouteMatch();
    */
   public function getParentRouteMatch();
 
-}
+  /**
+   * Returns a route match from a given request, if possible.
+   *
+   * @param \Symfony\Component\HttpFoundation\Request
+   *   The request.
+   *
+   * @return \Drupal\Core\Routing\RouteMatchInterface|NULL
+   *   THe matching route match, or NULL if there is no matching one.
+   */
+  public function getRouteMatchFromRequest(Request $request);
 
+}
diff --git a/core/modules/comment/comment.module b/core/modules/comment/comment.module
index 4978551785052cee8e1657494774e3ee3eea2a7c..79f0d3860a87c128fac23765dd54e73eff495be3 100644
--- a/core/modules/comment/comment.module
+++ b/core/modules/comment/comment.module
@@ -314,9 +314,9 @@ function comment_view_multiple($comments, $view_mode = 'full', $langcode = NULL)
  * Implements hook_form_FORM_ID_alter() for field_ui_field_storage_add_form.
  */
 function comment_form_field_ui_field_storage_add_form_alter(&$form, FormStateInterface $form_state) {
-  $request = \Drupal::request();
-  if ($form_state->get('entity_type_id') == 'comment' && $request->attributes->has('commented_entity_type')) {
-    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($request->attributes->get('commented_entity_type'), $request->attributes->get('field_name'));
+  $route_match = \Drupal::routeMatch();
+  if ($form_state->get('entity_type_id') == 'comment' && $route_match->getParameter('commented_entity_type')) {
+    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($route_match->getParameter('commented_entity_type'), $route_match->getParameter('field_name'));
   }
   if (!_comment_entity_uses_integer_id($form_state->get('entity_type_id'))) {
     // You cannot use comment fields on entity types with non-integer IDs.
@@ -328,9 +328,9 @@ function comment_form_field_ui_field_storage_add_form_alter(&$form, FormStateInt
  * Implements hook_form_FORM_ID_alter().
  */
 function comment_form_field_ui_form_display_overview_form_alter(&$form, FormStateInterface $form_state) {
-  $request = \Drupal::request();
-  if ($form['#entity_type'] == 'comment' && $request->attributes->has('commented_entity_type')) {
-    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($request->attributes->get('commented_entity_type'), $request->attributes->get('field_name'));
+  $route_match = \Drupal::routeMatch();
+  if ($form['#entity_type'] == 'comment' && $route_match->getParameter('commented_entity_type')) {
+    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($route_match->getParameter('commented_entity_type'), $route_match->getParameter('field_name'));
   }
 }
 
@@ -338,9 +338,9 @@ function comment_form_field_ui_form_display_overview_form_alter(&$form, FormStat
  * Implements hook_form_FORM_ID_alter().
  */
 function comment_form_field_ui_display_overview_form_alter(&$form, FormStateInterface $form_state) {
-  $request = \Drupal::request();
-  if ($form['#entity_type'] == 'comment' && $request->attributes->has('commented_entity_type')) {
-    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($request->attributes->get('commented_entity_type'), $request->attributes->get('field_name'));
+  $route_match = \Drupal::routeMatch();
+  if ($form['#entity_type'] == 'comment' && $route_match->getParameter('commented_entity_type')) {
+    $form['#title'] = \Drupal::service('comment.manager')->getFieldUIPageTitle($route_match->getParameter('commented_entity_type'), $route_match->getParameter('field_name'));
   }
 }
 
diff --git a/core/modules/config_translation/src/ConfigEntityMapper.php b/core/modules/config_translation/src/ConfigEntityMapper.php
index 2cbc78e38edc04ae305bd20216b50d1bb23a431b..848a6ce2cf6844bb2d0430660e0a289526a52f6c 100644
--- a/core/modules/config_translation/src/ConfigEntityMapper.php
+++ b/core/modules/config_translation/src/ConfigEntityMapper.php
@@ -11,6 +11,7 @@
 use Drupal\Core\Config\TypedConfigManagerInterface;
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\Core\Entity\EntityManagerInterface;
+use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Routing\RouteProviderInterface;
 use Drupal\Core\StringTranslation\TranslationInterface;
 use Drupal\Core\Url;
diff --git a/core/modules/config_translation/src/ConfigMapperInterface.php b/core/modules/config_translation/src/ConfigMapperInterface.php
index ba75aa2b62980d63cf715b115bd3ab87e0e2c52b..ac3d531a2aba12b2ec04d7d14a175f728f485d73 100644
--- a/core/modules/config_translation/src/ConfigMapperInterface.php
+++ b/core/modules/config_translation/src/ConfigMapperInterface.php
@@ -281,6 +281,8 @@ public function hasTranslation(LanguageInterface $language);
   /**
    * Populate the config mapper with request data.
    *
+   * @todo Replace $request with RouteMatch https://www.drupal.org/node/2295255.
+   *
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   Page request object.
    */
diff --git a/core/modules/content_translation/src/Controller/ContentTranslationController.php b/core/modules/content_translation/src/Controller/ContentTranslationController.php
index e3622dc9ddf3249a1e043f0be7cdacbef12803ba..dc74210738fa2dae98d4a314dbfac33300179525 100644
--- a/core/modules/content_translation/src/Controller/ContentTranslationController.php
+++ b/core/modules/content_translation/src/Controller/ContentTranslationController.php
@@ -10,8 +10,8 @@
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\ContentEntityInterface;
 use Drupal\Core\Language\LanguageInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Url;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Base class for entity translation controllers.
@@ -37,16 +37,15 @@ public function prepareTranslation(ContentEntityInterface $entity, LanguageInter
   /**
    * Builds the translations overview page.
    *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object from which to extract the entity type.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
    * @param string $entity_type_id
    *   (optional) The entity type ID.
-   *
-   * @return array
-   *   Array of page elements to render.
+   * @return array Array of page elements to render.
+   * Array of page elements to render.
    */
-  public function overview(Request $request, $entity_type_id = NULL) {
-    $entity = $request->attributes->get($entity_type_id);
+  public function overview(RouteMatchInterface $route_match, $entity_type_id = NULL) {
+    $entity = $route_match->getParameter($entity_type_id);
     $account = $this->currentUser();
     $handler = $this->entityManager()->getHandler($entity_type_id, 'translation');
 
@@ -252,16 +251,16 @@ public function overview(Request $request, $entity_type_id = NULL) {
    * @param \Drupal\Core\Language\LanguageInterface $target
    *   The language of the translated values. Defaults to the current content
    *   language.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object from which to extract the entity type.
+   * @param \Drupal\Core\Routing\RouteMatchInterface
+   *   The route match object from which to extract the entity type.
    * @param string $entity_type_id
    *   (optional) The entity type ID.
    *
    * @return array
    *   A processed form array ready to be rendered.
    */
-  public function add(LanguageInterface $source, LanguageInterface $target, Request $request, $entity_type_id = NULL) {
-    $entity = $request->attributes->get($entity_type_id);
+  public function add(LanguageInterface $source, LanguageInterface $target, RouteMatchInterface $route_match, $entity_type_id = NULL) {
+    $entity = $route_match->getParameter($entity_type_id);
 
     // @todo Exploit the upcoming hook_entity_prepare() when available.
     // See https://www.drupal.org/node/1810394.
@@ -287,16 +286,16 @@ public function add(LanguageInterface $source, LanguageInterface $target, Reques
    * @param \Drupal\Core\Language\LanguageInterface $language
    *   The language of the translated values. Defaults to the current content
    *   language.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object from which to extract the entity type.
+   * @param \Drupal\Core\Routing\RouteMatchInterface
+   *   The route match object from which to extract the entity type.
    * @param string $entity_type_id
    *   (optional) The entity type ID.
    *
    * @return array
    *   A processed form array ready to be rendered.
    */
-  public function edit(LanguageInterface $language, Request $request, $entity_type_id = NULL) {
-    $entity = $request->attributes->get($entity_type_id);
+  public function edit(LanguageInterface $language, RouteMatchInterface $route_match, $entity_type_id = NULL) {
+    $entity = $route_match->getParameter($entity_type_id);
 
     // @todo Provide a way to figure out the default form operation. Maybe like
     //   $operation = isset($info['default_operation']) ? $info['default_operation'] : 'default';
diff --git a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
index b6b16e62bfd920fb14978180625227832298c607..015ae960de86764f16031cda8952161be86672a1 100644
--- a/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
+++ b/core/modules/content_translation/src/Form/ContentTranslationDeleteForm.php
@@ -9,6 +9,7 @@
 
 use Drupal\Core\Form\ConfirmFormBase;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Language\LanguageInterface;
 use Drupal\Core\Url;
 
 /**
@@ -40,9 +41,9 @@ public function getFormId() {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL, $language = NULL) {
-    $this->entity = $this->getRequest()->attributes->get($entity_type_id);
-    $this->language = language_load($language);
+  public function buildForm(array $form, FormStateInterface $form_state, $entity_type_id = NULL, LanguageInterface $language = NULL) {
+    $this->entity = $this->getRouteMatch()->getParameter($entity_type_id);
+    $this->language = $language;
     return parent::buildForm($form, $form_state);
   }
 
diff --git a/core/modules/field_ui/src/Controller/FieldConfigListController.php b/core/modules/field_ui/src/Controller/FieldConfigListController.php
index 8ed9be080c1edad6a97b6e344e01dc37aa253a8c..4f1a3f0d397f9a98209c83db7fcf9abc230650e1 100644
--- a/core/modules/field_ui/src/Controller/FieldConfigListController.php
+++ b/core/modules/field_ui/src/Controller/FieldConfigListController.php
@@ -8,6 +8,7 @@
 namespace Drupal\field_ui\Controller;
 
 use Drupal\Core\Entity\Controller\EntityListController;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\HttpFoundation\Request;
 
 /**
@@ -22,18 +23,18 @@ class FieldConfigListController extends EntityListController {
    *   The entity type.
    * @param string $bundle
    *   The entity bundle.
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The current request.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The current route match.
    *
    * @return array
    *   A render array as expected by drupal_render().
    */
-  public function listing($entity_type_id = NULL, $bundle = NULL, Request $request = NULL) {
+  public function listing($entity_type_id = NULL, $bundle = NULL, RouteMatchInterface $route_match = NULL) {
     if (!$bundle) {
       $entity_info = $this->entityManager()->getDefinition($entity_type_id);
-      $bundle = $request->attributes->get('_raw_variables')->get($entity_info->getBundleEntityType());
+      $bundle = $route_match->getRawParameter($entity_info->getBundleEntityType());
     }
-    return $this->entityManager()->getListBuilder('field_config')->render($entity_type_id, $bundle, $request);
+    return $this->entityManager()->getListBuilder('field_config')->render($entity_type_id, $bundle);
   }
 
 }
diff --git a/core/modules/field_ui/src/Form/FieldStorageAddForm.php b/core/modules/field_ui/src/Form/FieldStorageAddForm.php
index e9f15a7cfe88ea00a53e87e519708a48054f09d1..f4f2358b4f07da4b47d2a8ba3cbf75eed7c0c979 100644
--- a/core/modules/field_ui/src/Form/FieldStorageAddForm.php
+++ b/core/modules/field_ui/src/Form/FieldStorageAddForm.php
@@ -122,7 +122,7 @@ public function buildForm(array $form, FormStateInterface $form_state, $entity_t
       $form_state->set('entity_type_id', $entity_type_id);
     }
     if (!$form_state->get('bundle')) {
-      $bundle = $bundle ?: $this->getRequest()->attributes->get('_raw_variables')->get($this->bundleEntityTypeId);
+      $bundle = $bundle ?: $this->getRouteMatch()->getRawParameter($this->bundleEntityTypeId);
       $form_state->set('bundle', $bundle);
     }
 
diff --git a/core/modules/node/src/Plugin/views/argument_default/Node.php b/core/modules/node/src/Plugin/views/argument_default/Node.php
index f1be8d69b64b3fe31808d8e2debc0697aee398b8..3df56fb4e8a97b601808d9da7c447bf1f9f58121 100644
--- a/core/modules/node/src/Plugin/views/argument_default/Node.php
+++ b/core/modules/node/src/Plugin/views/argument_default/Node.php
@@ -7,9 +7,11 @@
 
 namespace Drupal\node\Plugin\views\argument_default;
 
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\views\Plugin\CacheablePluginInterface;
 use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
 use Drupal\node\NodeInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Default argument plugin to extract a node.
@@ -23,11 +25,49 @@
  */
 class Node extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new Date instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('current_route_match')
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
   public function getArgument() {
-    if (($node = $this->view->getRequest()->attributes->get('node')) && $node instanceof NodeInterface) {
+    if (($node = $this->routeMatch->getParameter('node')) && $node instanceof NodeInterface) {
       return $node->id();
     }
   }
diff --git a/core/modules/rest/src/RequestHandler.php b/core/modules/rest/src/RequestHandler.php
index c31600d0c8ff5a02498e4145e3375759a5504d7c..0ddfdd72977224f64ac2b06f42ddc77585d2493b 100644
--- a/core/modules/rest/src/RequestHandler.php
+++ b/core/modules/rest/src/RequestHandler.php
@@ -31,11 +31,13 @@ class RequestHandler implements ContainerAwareInterface {
    *   The route match.
    * @param \Symfony\Component\HttpFoundation\Request $request
    *   The HTTP request object.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
    *
    * @return \Symfony\Component\HttpFoundation\Response
    *   The response object.
    */
-  public function handle(RouteMatchInterface $route_match, Request $request) {
+  public function handle(RouteMatchInterface $route_match, Request $request, RouteMatchInterface $route_match) {
 
     $plugin = $route_match->getRouteObject()->getDefault('_plugin');
     $method = strtolower($request->getMethod());
@@ -76,7 +78,7 @@ public function handle(RouteMatchInterface $route_match, Request $request) {
 
     // Determine the request parameters that should be passed to the resource
     // plugin.
-    $route_parameters = $request->attributes->get('_route_params');
+    $route_parameters = $route_match->getParameters();
     $parameters = array();
     // Filter out all internal parameters starting with "_".
     foreach ($route_parameters as $key => $parameter) {
diff --git a/core/modules/system/entity.api.php b/core/modules/system/entity.api.php
index 189e8a2c82e37b3fc7618e3e6cf93e3cbe161995..6a970602fc01ed6b6d7c8d56a424cba093f9e6d5 100644
--- a/core/modules/system/entity.api.php
+++ b/core/modules/system/entity.api.php
@@ -893,8 +893,8 @@ function hook_ENTITY_TYPE_storage_load(array $entities) {
  */
 function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  if ($entity instanceof ContentEntityInterface && $entity->isTranslatable()) {
-   $attributes = \Drupal::request()->attributes;
-   \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $attributes->get('source_langcode'));
+   $route_match = \Drupal::routeMatch();
+   \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $route_match->getParameter('source_langcode'));
   }
 }
 
@@ -909,8 +909,8 @@ function hook_entity_presave(Drupal\Core\Entity\EntityInterface $entity) {
  */
 function hook_ENTITY_TYPE_presave(Drupal\Core\Entity\EntityInterface $entity) {
   if ($entity->isTranslatable()) {
-    $attributes = \Drupal::request()->attributes;
-    \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $attributes->get('source_langcode'));
+    $route_match = \Drupal::routeMatch();
+    \Drupal::service('content_translation.synchronizer')->synchronizeFields($entity, $entity->language()->getId(), $route_match->getParameter('source_langcode'));
   }
 }
 
diff --git a/core/modules/system/src/PathBasedBreadcrumbBuilder.php b/core/modules/system/src/PathBasedBreadcrumbBuilder.php
index 1075ee7cad82459081ce9c78e6e6d08dd6a83753..05693312e1096626273b82e46f4db48b23e22d2a 100644
--- a/core/modules/system/src/PathBasedBreadcrumbBuilder.php
+++ b/core/modules/system/src/PathBasedBreadcrumbBuilder.php
@@ -14,10 +14,12 @@
 use Drupal\Core\Link;
 use Drupal\Core\ParamConverter\ParamNotConvertedException;
 use Drupal\Core\PathProcessor\InboundPathProcessorInterface;
+use Drupal\Core\Routing\RouteMatch;
 use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\StringTranslation\StringTranslationTrait;
 use Drupal\Component\Utility\Unicode;
+use Drupal\Core\Url;
 use Symfony\Component\HttpFoundation\Request;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\HttpKernel\Exception\AccessDeniedHttpException;
@@ -139,9 +141,10 @@ public function build(RouteMatchInterface $route_match) {
       // Copy the path elements for up-casting.
       $route_request = $this->getRequestForPath(implode('/', $path_elements), $exclude);
       if ($route_request) {
-        $access = $this->accessManager->checkRequest($route_request, $this->currentUser);
+        $route_match = RouteMatch::createFromRequest($route_request);
+        $access = $this->accessManager->check($route_match, $this->currentUser);
         if ($access) {
-          $title = $this->titleResolver->getTitle($route_request, $route_request->attributes->get(RouteObjectInterface::ROUTE_OBJECT));
+          $title = $this->titleResolver->getTitle($route_request, $route_match->getRouteObject());
         }
         if ($access) {
           if (!isset($title)) {
@@ -149,7 +152,8 @@ public function build(RouteMatchInterface $route_match) {
             // route is missing a _title or _title_callback attribute.
             $title = str_replace(array('-', '_'), ' ', Unicode::ucfirst(end($path_elements)));
           }
-          $links[] = Link::createFromRoute($title, $route_request->attributes->get(RouteObjectInterface::ROUTE_NAME), $route_request->attributes->get('_raw_variables')->all());
+          $url = Url::fromRouteMatch($route_match);
+          $links[] = new Link($title, $url);
         }
       }
 
diff --git a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
index 00619ef25f4458cf7c4cc18b7254000f2bdee874..bf5fa29053a451f9261c4a8470f8c41eeb56af5c 100644
--- a/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
+++ b/core/modules/system/tests/modules/entity_test/src/Controller/EntityTestController.php
@@ -10,8 +10,8 @@
 use Drupal\Core\Cache\Cache;
 use Drupal\Core\Controller\ControllerBase;
 use Drupal\Core\Entity\Query\QueryFactory;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Controller routines for entity_test routes.
@@ -65,8 +65,8 @@ public function testAdd($entity_type_id) {
   /**
    * Displays the 'Edit existing entity_test' form.
    *
-   * @param \Symfony\Component\HttpFoundation\Request $request
-   *   The request object to get entity type from.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match object to get entity type from.
    * @param string $entity_type_id
    *   The entity type ID.
    *
@@ -75,8 +75,8 @@ public function testAdd($entity_type_id) {
    *
    * @see \Drupal\entity_test\Routing\EntityTestRoutes::routes()
    */
-  public function testEdit(Request $request, $entity_type_id) {
-    $entity = $request->attributes->get($entity_type_id);
+  public function testEdit(RouteMatchInterface $route_match, $entity_type_id) {
+    $entity = $route_match->getParameter($entity_type_id);
     $form = $this->entityFormBuilder()->getForm($entity);
     $form['#title'] = $entity->label();
     return $form;
diff --git a/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php b/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php
index a3e5064342871cae893ba2161223cd58711a6005..1b96b3da093df1ac1163edc88f2b970f517c8f77 100644
--- a/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php
+++ b/core/modules/system/tests/modules/form_test/src/FormTestControllerObject.php
@@ -10,6 +10,7 @@
 use Drupal\Core\Form\FormBase;
 use Drupal\Core\Form\FormStateInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Provides a test form object.
@@ -34,11 +35,11 @@ public static function create(ContainerInterface $container) {
   /**
    * {@inheritdoc}
    */
-  public function buildForm(array $form, FormStateInterface $form_state, $custom_attributes = NULL) {
+  public function buildForm(array $form, FormStateInterface $form_state, Request $request = NULL, $custom_attributes = NULL) {
     $form['element'] = array('#markup' => 'The FormTestControllerObject::buildForm() method was used for this form.');
 
     $form['custom_attribute']['#markup'] = $custom_attributes;
-    $form['request_attribute']['#markup'] = $this->getRequest()->attributes->get('request_attribute');
+    $form['request_attribute']['#markup'] = $request->attributes->get('request_attribute');
 
     $form['bananas'] = array(
       '#type' => 'textfield',
diff --git a/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php b/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
index 33f52fcfad9b73a256c0b227868d3ea654d6c2e0..282261232fcde99d52e7f59db3468b19a3209985 100644
--- a/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
+++ b/core/modules/system/tests/modules/paramconverter_test/src/TestControllers.php
@@ -9,15 +9,13 @@
 
 use Drupal\Core\Entity\EntityInterface;
 use Drupal\node\NodeInterface;
-use Symfony\Component\HttpFoundation\Request;
 
 /**
  * Controller routine for testing the paramconverter.
  */
 class TestControllers {
 
-  public function testUserNodeFoo(EntityInterface $user, NodeInterface $node, Request $request) {
-    $foo = $request->attributes->get('foo');
+  public function testUserNodeFoo(EntityInterface $user, NodeInterface $node, $foo) {
     $foo = is_object($foo) ? $foo->label() : $foo;
     return ['#markup' => "user: {$user->label()}, node: {$node->label()}, foo: $foo"];
   }
diff --git a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php
index 8ceea8ac9ea6839e0ce5f30a2644af3b599cbece..7daf8c2fa9c24bc1d7b3600ea2aaa56067015677 100644
--- a/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php
+++ b/core/modules/system/tests/src/Unit/Breadcrumbs/PathBasedBreadcrumbBuilderTest.php
@@ -326,8 +326,8 @@ public function testBuildWithUserPath() {
    */
   public function setupAccessManagerToAllow() {
     $this->accessManager->expects($this->any())
-      ->method('checkRequest')
-      ->will($this->returnValue(AccessResult::allowed()));
+      ->method('check')
+      ->willReturn(TRUE);
   }
 
   protected function setupStubPathProcessor() {
diff --git a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
index 2cd7a13430f11079cb50053ce5506f39b31d521f..a90b5e193054932a04fce252c0dfd1427bcf9600 100644
--- a/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
+++ b/core/modules/taxonomy/src/Plugin/views/argument_default/Tid.php
@@ -8,6 +8,7 @@
 namespace Drupal\taxonomy\Plugin\views\argument_default;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\taxonomy\TermInterface;
 use Drupal\views\Plugin\CacheablePluginInterface;
 use Drupal\views\ViewExecutable;
@@ -27,6 +28,44 @@
  */
 class Tid extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new Date instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('current_route_match')
+    );
+  }
+
   /**
    * Overrides \Drupal\views\Plugin\views\Plugin\views\PluginBase::init().
    */
@@ -126,14 +165,14 @@ public function submitOptionsForm(&$form, FormStateInterface $form_state, &$opti
   public function getArgument() {
     // Load default argument from taxonomy page.
     if (!empty($this->options['term_page'])) {
-      if (($taxonomy_term = $this->view->getRequest()->attributes->get('taxonomy_term')) && $taxonomy_term instanceof TermInterface) {
+      if (($taxonomy_term = $this->routeMatch->getParameter('taxonomy_term')) && $taxonomy_term instanceof TermInterface) {
         return $taxonomy_term->id();
       }
     }
     // Load default argument from node.
     if (!empty($this->options['node'])) {
       // Just check, if a node could be detected.
-      if (($node = $this->view->getRequest()->attributes->get('node')) && $node instanceof NodeInterface) {
+      if (($node = $this->routeMatch->getParameter('node')) && $node instanceof NodeInterface) {
         $taxonomy = array();
         foreach ($node->getFieldDefinitions() as $field) {
           if ($field->getType() == 'taxonomy_term_reference') {
diff --git a/core/modules/update/update.module b/core/modules/update/update.module
index a3d92f5177257d7c3e85ef8b06111358688c431c..c445986619620933d1f218d529ce4a510bcadac3 100644
--- a/core/modules/update/update.module
+++ b/core/modules/update/update.module
@@ -119,7 +119,8 @@ function update_help($route_name, RouteMatchInterface $route_match) {
 function update_page_top() {
   /** @var \Drupal\Core\Routing\AdminContext $admin_context */
   $admin_context = \Drupal::service('router.admin_context');
-  if ($admin_context->isAdminRoute(\Drupal::request()->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) && \Drupal::currentUser()->hasPermission('administer site configuration')) {
+  $route_match = \Drupal::routeMatch();
+  if ($admin_context->isAdminRoute($route_match->getRouteObject()) && \Drupal::currentUser()->hasPermission('administer site configuration')) {
     $route_name = \Drupal::routeMatch()->getRouteName();
     switch ($route_name) {
       // These pages don't need additional nagging.
diff --git a/core/modules/user/src/Plugin/Block/UserLoginBlock.php b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
index 47177a52f4b1c041ca6276cec3927b1ceb19b573..9e666768c1f250063671427a13b4574e7117ed31 100644
--- a/core/modules/user/src/Plugin/Block/UserLoginBlock.php
+++ b/core/modules/user/src/Plugin/Block/UserLoginBlock.php
@@ -7,11 +7,13 @@
 
 namespace Drupal\user\Plugin\Block;
 
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\Core\Routing\UrlGeneratorTrait;
 use Drupal\Core\Url;
 use Drupal\Core\Session\AccountInterface;
 use Drupal\Core\Block\BlockBase;
-use Symfony\Cmf\Component\Routing\RouteObjectInterface;
+use Symfony\Component\DependencyInjection\ContainerInterface;
 
 /**
  * Provides a 'User login' block.
@@ -22,15 +24,56 @@
  *   category = @Translation("Forms")
  * )
  */
-class UserLoginBlock extends BlockBase {
+class UserLoginBlock extends BlockBase implements ContainerFactoryPluginInterface {
 
   use UrlGeneratorTrait;
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new UserLoginBlock instance.
+   *
+   * @param array $configuration
+   *   The plugin configuration, i.e. an array with configuration values keyed
+   *   by configuration option name. The special key 'context' may be used to
+   *   initialize the defined contexts by setting it to an array of context
+   *   values keyed by context names.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('current_route_match')
+    );
+  }
+
+
   /**
    * {@inheritdoc}
    */
   protected function blockAccess(AccountInterface $account) {
-    $route_name = \Drupal::request()->attributes->get(RouteObjectInterface::ROUTE_NAME);
+    $route_name = $this->routeMatch->getRouteName();
     return ($account->isAnonymous() && !in_array($route_name, array('user.register', 'user.login', 'user.logout')));
   }
 
diff --git a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
index 7e17832077432d958a87e8486d652fc6f889378e..17b3cd69fabd17204adf4ea01d2811ced6bf3d15 100644
--- a/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
+++ b/core/modules/user/src/Plugin/LanguageNegotiation/LanguageNegotiationUserAdmin.php
@@ -10,6 +10,8 @@
 use Drupal\Core\PathProcessor\PathProcessorManager;
 use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
 use Drupal\Core\Routing\AdminContext;
+use Drupal\Core\Routing\RouteMatch;
+use Drupal\Core\Routing\StackedRouteMatchInterface;
 use Drupal\language\LanguageNegotiationMethodBase;
 use Symfony\Cmf\Component\Routing\RouteObjectInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -60,6 +62,13 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
    */
   protected $pathProcessorManager;
 
+  /**
+   * The stacked route match.
+   *
+   * @var \Drupal\Core\Routing\StackedRouteMatchInterface
+   */
+  protected $stackedRouteMatch;
+
   /**
    * Constructs a new LanguageNegotiationUserAdmin instance.
    *
@@ -69,11 +78,14 @@ class LanguageNegotiationUserAdmin extends LanguageNegotiationMethodBase impleme
    *   The router.
    * @param \Drupal\Core\PathProcessor\PathProcessorManager $path_processor_manager
    *   The path processor manager.
+   * @param \Drupal\Core\Routing\StackedRouteMatchInterface $stacked_route_match
+   *   The stacked route match.
    */
-  public function __construct(AdminContext $admin_context, UrlMatcherInterface $router, PathProcessorManager $path_processor_manager) {
+  public function __construct(AdminContext $admin_context, UrlMatcherInterface $router, PathProcessorManager $path_processor_manager, StackedRouteMatchInterface $stacked_route_match) {
     $this->adminContext = $admin_context;
     $this->router = $router;
     $this->pathProcessorManager = $path_processor_manager;
+    $this->stackedRouteMatch = $stacked_route_match;
   }
 
   /**
@@ -83,7 +95,8 @@ public static function create(ContainerInterface $container, array $configuratio
     return new static(
       $container->get('router.admin_context'),
       $container->get('router'),
-      $container->get('path_processor_manager')
+      $container->get('path_processor_manager'),
+      $container->get('current_route_match')
     );
   }
 
@@ -117,7 +130,8 @@ protected function isAdminPath(Request $request) {
       // If called from an event subscriber, the request may not have the route
       // object yet (it is still being built), so use the router to look up
       // based on the path.
-      if (!$route_object = $request->attributes->get(RouteObjectInterface::ROUTE_OBJECT)) {
+      $route_match = $this->stackedRouteMatch->getRouteMatchFromRequest($request);
+      if ($route_match && !$route_object = $route_match->getRouteObject()) {
         try {
           // Process the path as an inbound path. This will remove any language
           // prefixes and other path components that inbound processing would
diff --git a/core/modules/user/src/Plugin/views/argument_default/User.php b/core/modules/user/src/Plugin/views/argument_default/User.php
index 850ee2ff77f2086738c243269ff3d9ede8cba923..77fa69f838413f9012de8a8dbbd6ce4eb1bc924d 100644
--- a/core/modules/user/src/Plugin/views/argument_default/User.php
+++ b/core/modules/user/src/Plugin/views/argument_default/User.php
@@ -8,6 +8,7 @@
 namespace Drupal\user\Plugin\views\argument_default;
 
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\views\Plugin\CacheablePluginInterface;
 use Drupal\views\Plugin\views\argument_default\ArgumentDefaultPluginBase;
 use Symfony\Component\DependencyInjection\ContainerInterface;
@@ -25,6 +26,44 @@
  */
 class User extends ArgumentDefaultPluginBase implements CacheablePluginInterface {
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new Date instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('current_route_match')
+    );
+  }
+
   /**
    * {@inheritdoc}
    */
@@ -52,16 +91,14 @@ public function buildOptionsForm(&$form, FormStateInterface $form_state) {
   public function getArgument() {
 
     // If there is a user object in the current route.
-    if ($this->view->getRequest()->attributes->has('user')) {
-      $user = $this->view->getRequest()->attributes->get('user');
+    if ($user = $this->routeMatch->getParameter('user')) {
       if ($user instanceof UserInterface) {
         return $user->id();
       }
     }
 
     // If option to use node author; and node in current route.
-    if (!empty($this->options['user']) && $this->view->getRequest()->attributes->has('node')) {
-      $node = $this->view->getRequest()->attributes->get('node');
+    if (!empty($this->options['user']) && $node = $this->routeMatch->getParameter('node')) {
       if ($node instanceof NodeInterface) {
         return $node->getOwnerId();
       }
diff --git a/core/modules/views/src/Plugin/views/argument/Date.php b/core/modules/views/src/Plugin/views/argument/Date.php
index 3a3db7f01e345999e7c20ae147c5b79f4b1a101e..457a0dff957fc54c407a7ffd66d2656fc5b34489 100644
--- a/core/modules/views/src/Plugin/views/argument/Date.php
+++ b/core/modules/views/src/Plugin/views/argument/Date.php
@@ -9,6 +9,8 @@
 
 use Drupal\Core\Database\Database;
 use Drupal\Core\Form\FormStateInterface;
+use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
+use Drupal\Core\Routing\RouteMatchInterface;
 use Drupal\node\NodeInterface;
 use Symfony\Component\DependencyInjection\ContainerInterface;
 use Symfony\Component\HttpFoundation\Request;
@@ -29,7 +31,7 @@
  *
  * @ViewsArgument("date")
  */
-class Date extends Formula {
+class Date extends Formula implements ContainerFactoryPluginInterface {
 
   /**
    * The date format used in the title.
@@ -47,6 +49,44 @@ class Date extends Formula {
 
   var $option_name = 'default_argument_date';
 
+  /**
+   * The route match.
+   *
+   * @var \Drupal\Core\Routing\RouteMatchInterface
+   */
+  protected $routeMatch;
+
+  /**
+   * Constructs a new Date instance.
+   *
+   * @param array $configuration
+   *   A configuration array containing information about the plugin instance.
+   * @param string $plugin_id
+   *   The plugin_id for the plugin instance.
+   * @param mixed $plugin_definition
+   *   The plugin implementation definition.
+   *
+   * @param \Drupal\Core\Routing\RouteMatchInterface $route_match
+   *   The route match.
+   */
+  public function __construct(array $configuration, $plugin_id, $plugin_definition, RouteMatchInterface $route_match) {
+    parent::__construct($configuration, $plugin_id, $plugin_definition);
+
+    $this->routeMatch = $route_match;
+  }
+
+  /**
+   * {@inheritdoc}
+   */
+  public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
+    return new static(
+      $configuration,
+      $plugin_id,
+      $plugin_definition,
+      $container->get('current_route_match')
+    );
+  }
+
   /**
    * Add an option to set the default value to the current date.
    */
@@ -66,7 +106,7 @@ public function getDefaultArgument($raw = FALSE) {
       return date($this->argFormat, REQUEST_TIME);
     }
     elseif (!$raw && in_array($this->options['default_argument_type'], array('node_created', 'node_changed'))) {
-      $node = $this->view->getRequest()->attributes->get('node');
+      $node = $this->routeMatch->getParameter('node');
 
       if (!($node instanceof NodeInterface)) {
         return parent::getDefaultArgument();
diff --git a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
index a49740df347a8bd5f219d15efa779147ced7d640..ce4c25b0063162d9499789916037a9569487e073 100644
--- a/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
+++ b/core/modules/views/src/Plugin/views/display/DisplayPluginBase.php
@@ -2582,7 +2582,7 @@ public function getSpecialBlocks() {
    */
   public function viewExposedFormBlocks() {
     // Avoid interfering with the admin forms.
-    $route_name = \Drupal::request()->attributes->get(RouteObjectInterface::ROUTE_NAME);
+    $route_name = \Drupal::routeMatch()->getRouteName();
     if (strpos($route_name, 'views_ui.') === 0) {
       return;
     }
diff --git a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
index 91491c8cccb13f461d00838fedc943d3156a3b24..d015a31c06f263f79ecd1baa9bdee81e5a39c895 100644
--- a/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
+++ b/core/tests/Drupal/Tests/Core/Controller/ControllerResolverTest.php
@@ -74,8 +74,8 @@ public function testGetArguments() {
     ));
     $arguments = $this->controllerResolver->getArguments($request, $controller);
 
-    $this->assertEquals($mock_entity, $arguments[0], 'Type hinted variables should use upcasted values.');
-    $this->assertEquals(1, $arguments[1], 'Not type hinted variables should use not upcasted values.');
+    $this->assertEquals($mock_entity, $arguments[0]);
+    $this->assertEquals($mock_account, $arguments[1]);
     $this->assertEquals(RouteMatch::createFromRequest($request), $arguments[2], 'Ensure that the route match object is passed along as well');
   }
 
diff --git a/core/tests/Drupal/Tests/Core/Routing/CurrentRouteMatchTest.php b/core/tests/Drupal/Tests/Core/Routing/CurrentRouteMatchTest.php
index 3293b84cc172f83965b4580906d714c2979bbdc4..1d2942d48e5d6e122d9f5aadf1ac8b473dde0e9d 100644
--- a/core/tests/Drupal/Tests/Core/Routing/CurrentRouteMatchTest.php
+++ b/core/tests/Drupal/Tests/Core/Routing/CurrentRouteMatchTest.php
@@ -78,4 +78,38 @@ public function testGetCurrentRouteObject() {
     $this->assertSame('1', $current_route_match->getParameter('foo'));
   }
 
+  /**
+   * @covers ::getRouteMatchFromRequest
+   */
+  public function testGetRouteMatchFromRequestWithRouting() {
+    $request_stack = new RequestStack();
+    $request = new Request();
+    $request_stack->push($request);
+    $current_route_match = new CurrentRouteMatch($request_stack);
+
+    $route_match = $current_route_match->getRouteMatchFromRequest($request);
+
+    $this->assertNull($route_match->getRouteName());
+    $this->assertNull($route_match->getRouteObject());
+  }
+
+  /**
+   * @covers ::getRouteMatchFromRequest
+   */
+  public function testGetRouteMatchFromRequest() {
+    $request_stack = new RequestStack();
+    $request = new Request();
+    $request_stack->push($request);
+    $route = new Route('/test-route/{foo}');
+
+    $request->attributes->set(RouteObjectInterface::ROUTE_NAME, 'test_route');
+    $request->attributes->set(RouteObjectInterface::ROUTE_OBJECT, $route);
+    $request->attributes->set('foo', '1');
+    $current_route_match = new CurrentRouteMatch($request_stack);
+
+    $route_match = $current_route_match->getRouteMatchFromRequest($request);
+    $this->assertEquals('test_route', $route_match->getRouteName());
+    $this->assertEquals($route, $route_match->getRouteObject());
+  }
+
 }