diff --git a/core/modules/block/block.module b/core/modules/block/block.module
index 6bc94f268117fe05928a999b36bc5b1e3150176d..b6a538113441d42660bc1cbf5d5ad8b77593967b 100644
--- a/core/modules/block/block.module
+++ b/core/modules/block/block.module
@@ -586,8 +586,8 @@ function template_preprocess_block(&$variables) {
 function block_user_role_delete($role) {
   foreach (entity_load_multiple('block') as $block_id => $block) {
     $visibility = $block->get('visibility');
-    if (isset($visibility['roles']['roles'][$role->id()])) {
-      unset($visibility['roles']['roles'][$role->id()]);
+    if (isset($visibility['roles']['roles'][$role->rid])) {
+      unset($visibility['roles']['roles'][$role->rid]);
       $block->set('visibility', $visibility);
       $block->save();
     }
diff --git a/core/modules/block/lib/Drupal/block/BlockBase.php b/core/modules/block/lib/Drupal/block/BlockBase.php
index c9812b7c5aa47392ecbe00ae95d715c8732d6c5c..a0f003decce3fd269f00560afe05afadc1e849d7 100644
--- a/core/modules/block/lib/Drupal/block/BlockBase.php
+++ b/core/modules/block/lib/Drupal/block/BlockBase.php
@@ -367,7 +367,7 @@ public function form($form, &$form_state) {
     }
 
     // Per-role visibility.
-    $role_options = array_map('check_plain', user_role_names());
+    $role_options = array_map('check_plain', user_roles());
     $form['visibility']['role'] = array(
       '#type' => 'details',
       '#title' => t('Roles'),
diff --git a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
index 91cab48acacd2b46f94dc5cd97d2da00cee70bc9..d049aa309b8f5d4188342421be83c32e13e504c6 100644
--- a/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
+++ b/core/modules/comment/lib/Drupal/comment/Tests/CommentLinksTest.php
@@ -39,7 +39,7 @@ function testCommentLinks() {
 
     // Remove additional user permissions from $this->web_user added by setUp(),
     // since this test is limited to anonymous and authenticated roles only.
-    entity_delete_multiple('user_role', array(key($this->web_user->roles)));
+    user_role_delete(key($this->web_user->roles));
 
     // Matrix of possible environmental conditions and configuration settings.
     // See setEnvironment() for details.
diff --git a/core/modules/filter/filter.admin.inc b/core/modules/filter/filter.admin.inc
index 4cc4a1f142ff26424919ddc2266135bfe63566a3..32a366869cb7841ed59b00c8458ee9ac9304fc30 100644
--- a/core/modules/filter/filter.admin.inc
+++ b/core/modules/filter/filter.admin.inc
@@ -169,7 +169,7 @@ function filter_admin_format_form($form, &$form_state, $format) {
   $form['roles'] = array(
     '#type' => 'checkboxes',
     '#title' => t('Roles'),
-    '#options' => array_map('check_plain', user_role_names()),
+    '#options' => array_map('check_plain', user_roles()),
     '#disabled' => $is_fallback,
     '#weight' => -10,
   );
diff --git a/core/modules/filter/filter.module b/core/modules/filter/filter.module
index 3ff344c25f60f797bb372a794f4bde8cb31de772..3e57f30ed39c44e916d5bc9d4f39810cc1a44f06 100644
--- a/core/modules/filter/filter.module
+++ b/core/modules/filter/filter.module
@@ -398,11 +398,11 @@ function filter_formats_reset() {
 function filter_get_roles_by_format($format) {
   // Handle the fallback format upfront (all roles have access to this format).
   if ($format->format == filter_fallback_format()) {
-    return user_role_names();
+    return user_roles();
   }
   // Do not list any roles if the permission does not exist.
   $permission = filter_permission_name($format);
-  return !empty($permission) ? user_role_names(FALSE, $permission) : array();
+  return !empty($permission) ? user_roles(FALSE, $permission) : array();
 }
 
 /**
diff --git a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
index 48faf24bc8248f116d928257b75edbd77c6b407c..a71a9e9f4ef70da54b558dea71b54f5dd3fc6405 100644
--- a/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
+++ b/core/modules/filter/lib/Drupal/filter/Tests/FilterFormatAccessTest.php
@@ -182,7 +182,7 @@ function testFormatRoles() {
     $this->assertFalse(in_array($this->disallowed_format->format, array_keys(filter_get_formats_by_role($rid))), 'A text format which a role does not have access to does not appear in the list of formats available to that role.');
 
     // Check that the fallback format is always allowed.
-    $this->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_role_names(), 'All roles have access to the fallback format.');
+    $this->assertEqual(filter_get_roles_by_format(filter_format_load(filter_fallback_format())), user_roles(), 'All roles have access to the fallback format.');
     $this->assertTrue(in_array(filter_fallback_format(), array_keys(filter_get_formats_by_role($rid))), 'The fallback format appears in the list of allowed formats for any role.');
   }
 
diff --git a/core/modules/node/node.views.inc b/core/modules/node/node.views.inc
index aa199e75cde3b15ab3411cf2b81d6ac2b35c6f5e..8f8d75f193e3a002e2985839856c58e3fb1e8a12 100644
--- a/core/modules/node/node.views.inc
+++ b/core/modules/node/node.views.inc
@@ -691,9 +691,11 @@ function node_views_analyze(ViewExecutable $view) {
         // check for no access control
         $access = $display->getOption('access');
         if (empty($access['type']) || $access['type'] == 'none') {
-          $result = db_select('role_permission', 'p')
-            ->fields('p', array('rid', 'permission'))
-            ->condition('p.rid', array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID), 'IN')
+          $select = db_select('role', 'r');
+          $select->innerJoin('role_permission', 'p', 'r.rid = p.rid');
+          $result = $select->fields('r', array('rid'))
+            ->fields('p', array('permission'))
+            ->condition('r.rid', array('anonymous', 'authenticated'), 'IN')
             ->condition('p.permission', 'access content')
             ->execute();
 
@@ -701,7 +703,7 @@ function node_views_analyze(ViewExecutable $view) {
             $role->safe = TRUE;
             $roles[$role->rid] = $role;
           }
-          if (!($roles[DRUPAL_ANONYMOUS_RID]->safe && $roles[DRUPAL_AUTHENTICATED_RID]->safe)) {
+          if (!($roles['anonymous']->safe && $roles['authenticated']->safe)) {
             $ret[] = Analyzer::formatMessage(t('Some roles lack permission to access content, but display %display has no access control.', array('%display' => $display->display['display_title'])), 'warning');
           }
           $filters = $display->getOption('filters');
diff --git a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
index 92c6ae5b6118a01da1c2392a468da946ee5783ec..0afbcd363ed38aa4bd0c07ac89ede9cdf76a584d 100644
--- a/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
+++ b/core/modules/simpletest/lib/Drupal/simpletest/WebTestBase.php
@@ -509,14 +509,11 @@ protected function drupalCreateUser(array $permissions = array()) {
    *   (optional) The role ID (machine name). Defaults to a random name.
    * @param string $name
    *   (optional) The label for the role. Defaults to a random string.
-   * @param integer $weight
-   *   (optional) The weight for the role. Defaults NULL so that entity_create()
-   *   sets the weight to maximum + 1.
    *
    * @return string
    *   Role ID of newly created role, or FALSE if role creation failed.
    */
-  protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NULL, $weight = NULL) {
+  protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NULL) {
     // Generate a random, lowercase machine name if none was passed.
     if (!isset($rid)) {
       $rid = strtolower($this->randomName(8));
@@ -532,26 +529,22 @@ protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NUL
     }
 
     // Create new role.
-    $role = entity_create('user_role', array(
-      'id' => $rid,
-      'label' => $name,
-    ));
-    if (!is_null($weight)) {
-      $role->set('weight', $weight);
-    }
-    $result = $role->save();
+    $role = new stdClass();
+    $role->rid = $rid;
+    $role->name = $name;
+    $result = user_role_save($role);
 
     $this->assertIdentical($result, SAVED_NEW, t('Created role ID @rid with name @name.', array(
-      '@name' => var_export($role->label(), TRUE),
-      '@rid' => var_export($role->id(), TRUE),
+      '@name' => var_export($role->name, TRUE),
+      '@rid' => var_export($role->rid, TRUE),
     )), t('Role'));
 
     if ($result === SAVED_NEW) {
       // Grant the specified permissions to the role, if any.
       if (!empty($permissions)) {
-        user_role_grant_permissions($role->id(), $permissions);
+        user_role_grant_permissions($role->rid, $permissions);
 
-        $assigned_permissions = db_query('SELECT permission FROM {role_permission} WHERE rid = :rid', array(':rid' => $role->id()))->fetchCol();
+        $assigned_permissions = db_query('SELECT permission FROM {role_permission} WHERE rid = :rid', array(':rid' => $role->rid))->fetchCol();
         $missing_permissions = array_diff($permissions, $assigned_permissions);
         if (!$missing_permissions) {
           $this->pass(t('Created permissions: @perms', array('@perms' => implode(', ', $permissions))), t('Role'));
@@ -560,7 +553,7 @@ protected function drupalCreateRole(array $permissions, $rid = NULL, $name = NUL
           $this->fail(t('Failed to create permissions: @perms', array('@perms' => implode(', ', $missing_permissions))), t('Role'));
         }
       }
-      return $role->id();
+      return $role->rid;
     }
     else {
       return FALSE;
diff --git a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserRoleUpgradePathTest.php b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserRoleUpgradePathTest.php
index 670420a2b7d8d92019fdd1248b5a423d9c44d188..f87c19f24cc727802983649c110c70b23f1cde3f 100644
--- a/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserRoleUpgradePathTest.php
+++ b/core/modules/system/lib/Drupal/system/Tests/Upgrade/UserRoleUpgradePathTest.php
@@ -73,19 +73,4 @@ public function testRoleUpgrade() {
     $this->drupalGet('admin/config/people/accounts');
     $this->assertFieldByName('user_admin_role', 3);
   }
-
-  /**
-   * Tests that roles were converted to config.
-   */
-  public function testRoleUpgradeToConfig() {
-    $this->assertTrue($this->performUpgrade(), 'The upgrade was completed successfully.');
-
-    // Check that the 'anonymous' role has been converted to config.
-    $anonymous = entity_load('user_role', DRUPAL_ANONYMOUS_RID);
-    $this->assertNotEqual(FALSE, $anonymous, "The 'anonymous' role has been converted to config.");
-
-    // Check that the 'authenticated' role has been converted to config.
-    $authenticated = entity_load('user_role', DRUPAL_AUTHENTICATED_RID);
-    $this->assertNotEqual(FALSE, $authenticated, "The 'authenticated' role has been converted to config.");
-  }
 }
diff --git a/core/modules/user/config/user.role.anonymous.yml b/core/modules/user/config/user.role.anonymous.yml
deleted file mode 100644
index 11defb06f09318cb56c9099bd3eeb022d5367abf..0000000000000000000000000000000000000000
--- a/core/modules/user/config/user.role.anonymous.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-id: anonymous
-label: Anonymous user
-weight: 0
diff --git a/core/modules/user/config/user.role.authenticated.yml b/core/modules/user/config/user.role.authenticated.yml
deleted file mode 100644
index dc4b65d6311d2b30dabb179d132612636fa7b4df..0000000000000000000000000000000000000000
--- a/core/modules/user/config/user.role.authenticated.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-id: authenticated
-label: Authenticated user
-weight: 1
diff --git a/core/modules/user/lib/Drupal/user/AccountFormController.php b/core/modules/user/lib/Drupal/user/AccountFormController.php
index 8f2f0c579397b5e27ed3327e049bdf86a8b1c807..7a1001d9fa63086b9bc533b2ba9c4ceb6fc6f256 100644
--- a/core/modules/user/lib/Drupal/user/AccountFormController.php
+++ b/core/modules/user/lib/Drupal/user/AccountFormController.php
@@ -129,7 +129,7 @@ public function form(array $form, array &$form_state, EntityInterface $account)
       '#access' => $admin,
     );
 
-    $roles = array_map('check_plain', user_role_names(TRUE));
+    $roles = array_map('check_plain', user_roles(TRUE));
     // The disabled checkbox subelement for the 'authenticated user' role
     // must be generated separately and added to the checkboxes element,
     // because of a limitation in Form API not supporting a single disabled
diff --git a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php b/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
deleted file mode 100644
index de17dc938a32cf1a77e77213c7189fd91a4abe42..0000000000000000000000000000000000000000
--- a/core/modules/user/lib/Drupal/user/Plugin/Core/Entity/Role.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\user\Plugin\Core\Entity\Role.
- */
-
-namespace Drupal\user\Plugin\Core\Entity;
-
-use Drupal\Core\Annotation\Plugin;
-use Drupal\Core\Annotation\Translation;
-use Drupal\Core\Config\Entity\ConfigEntityBase;
-
-/**
- * Defines the user role entity class.
- *
- * @Plugin(
- *   id = "user_role",
- *   label = @Translation("Role"),
- *   module = "user",
- *   controller_class = "Drupal\user\RoleStorageController",
- *   config_prefix = "user.role",
- *   entity_keys = {
- *     "id" = "id",
- *     "uuid" = "uuid",
- *     "label" = "label"
- *   }
- * )
- */
-class Role extends ConfigEntityBase {
-
-  /**
-   * The machine name of this role.
-   *
-   * @var string
-   */
-  public $id;
-
-  /**
-   * The UUID of this role.
-   *
-   * @var string
-   */
-  public $uuid;
-
-  /**
-   * The human-readable label of this role.
-   *
-   * @var string
-   */
-  public $label;
-
-  /**
-   * The weight of this role in administrative listings.
-   *
-   * @var int
-   */
-  public $weight;
-
-}
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php
index 146968a5b7c3b3eb94678ccf5000d09db3457c0c..2a07d792037e49ced3c58c2973b4ebf62c70ee68 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/access/Role.php
@@ -46,7 +46,7 @@ public function summaryTitle() {
       return t('Multiple roles');
     }
     else {
-      $rids = user_role_names();
+      $rids = user_roles();
       $rid = reset($this->options['role']);
       return check_plain($rids[$rid]);
     }
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
index da3bd92d70fa2eb95765597a9a7bc911c86847b1..634307e0d1e1c4367461bf1d32d3e442e5c50ce5 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument/RolesRid.php
@@ -23,7 +23,16 @@
 class RolesRid extends ManyToOne {
 
   function title_query() {
-    return array(entity_load('user_role', $this->value)->label());
+    $titles = array();
+
+    $query = db_select('role', 'r');
+    $query->addField('r', 'name');
+    $query->condition('r.rid', $this->value);
+    $result = $query->execute();
+    foreach ($result as $term) {
+      $titles[] = check_plain($term->name);
+    }
+    return $titles;
   }
 
 }
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
index 36a6a5a610e40a61b365801ce555eec9575ea7e0..a31b0af758664ab627649a8ced2e1aca180eaaae 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/argument_validator/User.php
@@ -56,7 +56,7 @@ public function buildOptionsForm(&$form, &$form_state) {
     $form['roles'] = array(
       '#type' => 'checkboxes',
       '#title' => t('Restrict to the selected roles'),
-      '#options' => array_map('check_plain', user_role_names(TRUE)),
+      '#options' => array_map('check_plain', user_roles(TRUE)),
       '#default_value' => $this->options['roles'],
       '#description' => t('If no roles are selected, users from any role will be allowed.'),
       '#states' => array(
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/field/Roles.php b/core/modules/user/lib/Drupal/user/Plugin/views/field/Roles.php
index 0c4b72fcbef4cbf915915a16469b3cf36850d190..c4eb0505368b293f5e37f3d258a1bc6869814fd1 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/field/Roles.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/field/Roles.php
@@ -47,26 +47,17 @@ function pre_render(&$values) {
     }
 
     if ($uids) {
-      $roles = user_roles();
-      $query = db_select('users_roles', 'u');
+      $query = db_select('role', 'r');
+      $query->join('users_roles', 'u', 'u.rid = r.rid');
+      $query->addField('r', 'name');
       $query->fields('u', array('uid', 'rid'));
-      $query->condition('u.rid', array_keys($roles));
       $query->condition('u.uid', $uids);
-
+      $query->orderBy('r.name');
       $result = $query->execute();
       foreach ($result as $role) {
-        $this->items[$role->uid][$role->rid]['role'] = check_plain($roles[$role->rid]->label());
+        $this->items[$role->uid][$role->rid]['role'] = check_plain($role->name);
         $this->items[$role->uid][$role->rid]['rid'] = $role->rid;
       }
-      // Sort the roles for each user by role weight.
-      $ordered_roles = array_flip(array_keys($roles));
-      foreach ($this->items as &$user_roles) {
-        // Create an array of rids that the user has in the role weight order.
-        $sorted_keys  = array_intersect_key($ordered_roles, $user_roles);
-        // Merge with the unsorted array of role information which has the
-        // effect of sorting it.
-        $user_roles = array_merge($sorted_keys, $user_roles);
-      }
     }
   }
 
diff --git a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php
index 139856ed397edc5a893d2c4577d1ae8473707b0b..8ee3569dbd6466c03e99f9bc6cc2b5a75dc57551 100644
--- a/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php
+++ b/core/modules/user/lib/Drupal/user/Plugin/views/filter/Roles.php
@@ -23,7 +23,7 @@
 class Roles extends ManyToOne {
 
   function get_value_options() {
-    $this->value_options = user_role_names(TRUE);
+    $this->value_options = user_roles(TRUE);
     unset($this->value_options[DRUPAL_AUTHENTICATED_RID]);
   }
 
diff --git a/core/modules/user/lib/Drupal/user/RoleStorageController.php b/core/modules/user/lib/Drupal/user/RoleStorageController.php
deleted file mode 100644
index f5f65758e1c789ecd26e0958e4ac635f8ce15118..0000000000000000000000000000000000000000
--- a/core/modules/user/lib/Drupal/user/RoleStorageController.php
+++ /dev/null
@@ -1,69 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\user\RoleStorageController.
- */
-
-namespace Drupal\user;
-
-use Drupal\Core\Config\Entity\ConfigStorageController;
-use Drupal\Core\Entity\EntityInterface;
-
-/**
- * Controller class for user roles.
- */
-class RoleStorageController extends ConfigStorageController {
-
-  /**
-   * Overrides ConfigStorageController::preSave().
-   */
-  public function preSave(EntityInterface $entity) {
-    if (!isset($entity->weight) && $roles = entity_load_multiple('user_role')) {
-      // Set a role weight to make this new role last.
-      $max = array_reduce($roles, function($max, $entity) {
-        return $max > $entity->weight ? $max : $entity->weight;
-      });
-      $entity->weight = $max + 1;
-    }
-    parent::preSave($entity);
-  }
-
-  /**
-   * Overrides ConfigStorageController::resetCache().
-   */
-  public function resetCache(array $ids = NULL) {
-    parent::resetCache($ids);
-
-    // Clear the user access cache.
-    drupal_static_reset('user_access');
-    drupal_static_reset('user_role_permissions');
-  }
-
-  /**
-   * Overrides ConfigStorageController::postDelete().
-   */
-  protected function postDelete($entities) {
-    $rids = array_keys($entities);
-
-    // Delete permission assignments.
-    db_delete('role_permission')
-      ->condition('rid', $rids)
-      ->execute();
-    // Remove the role from all users.
-    db_delete('users_roles')
-      ->condition('rid', $rids)
-      ->execute();
-  }
-
-  /**
-   * Overrides ConfigStorageController::attachLoad().
-   */
-  protected function attachLoad(&$queried_entities, $revision_id = FALSE) {
-    // Sort the queried roles by their weight.
-    uasort($queried_entities, 'Drupal\Core\Config\Entity\ConfigEntityBase::sort');
-
-    parent::attachLoad($queried_entities, $revision_id);
-  }
-
-}
diff --git a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php
index d322a640743177e4d04d0f41fce01b2fe7d6ec1b..50d4da7eabe9ca3e330439324acec3ae0ef907fd 100644
--- a/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php
+++ b/core/modules/user/lib/Drupal/user/Tests/UserRoleAdminTest.php
@@ -37,10 +37,10 @@ function testRoleAdministration() {
     // correspond to an integer, to test that the role administration pages
     // correctly distinguish between role names and IDs.)
     $role_name = '123';
-    $edit = array('role[label]' => $role_name, 'role[id]' => $role_name);
+    $edit = array('role[name]' => $role_name, 'role[rid]' => $role_name);
     $this->drupalPost('admin/people/roles', $edit, t('Add role'));
     $this->assertText(t('The role has been added.'), 'The role has been added.');
-    $role = entity_load('user_role', $role_name);
+    $role = user_role_load($role_name);
     $this->assertTrue(is_object($role), 'The role was successfully retrieved from the database.');
 
     // Try adding a duplicate role.
@@ -50,18 +50,18 @@ function testRoleAdministration() {
     // Test renaming a role.
     $old_name = $role_name;
     $role_name = '456';
-    $edit = array('role[label]' => $role_name);
-    $this->drupalPost("admin/people/roles/edit/{$role->id()}", $edit, t('Save role'));
+    $edit = array('role[name]' => $role_name);
+    $this->drupalPost("admin/people/roles/edit/{$role->rid}", $edit, t('Save role'));
     $this->assertText(t('The role has been renamed.'), 'The role has been renamed.');
-    $new_role = entity_load('user_role', $old_name);
-    $this->assertEqual($new_role->label(), $role_name, 'The role name has been successfully changed.');
+    $new_role = user_role_load($old_name);
+    $this->assertEqual($new_role->name, $role_name, 'The role name has been successfully changed.');
 
     // Test deleting a role.
-    $this->drupalPost("admin/people/roles/edit/{$role->id()}", NULL, t('Delete role'));
+    $this->drupalPost("admin/people/roles/edit/{$role->rid}", NULL, t('Delete role'));
     $this->drupalPost(NULL, NULL, t('Delete'));
     $this->assertText(t('The role has been deleted.'), 'The role has been deleted');
-    $this->assertNoLinkByHref("admin/people/roles/edit/{$role->id()}", 'Role edit link removed.');
-    $this->assertFalse(entity_load('user_role', $role_name), 'A deleted role can no longer be loaded.');
+    $this->assertNoLinkByHref("admin/people/roles/edit/{$role->rid}", 'Role edit link removed.');
+    $this->assertFalse(user_role_load($role_name), 'A deleted role can no longer be loaded.');
 
     // Make sure that the system-defined roles can be edited via the user
     // interface.
@@ -74,36 +74,24 @@ function testRoleAdministration() {
   }
 
   /**
-   * Test user role weight change operation and ordering.
+   * Test user role weight change operation.
    */
-  function testRoleWeightOrdering() {
+  function testRoleWeightChange() {
     $this->drupalLogin($this->admin_user);
-    $roles = user_roles();
-    $weight = count($roles);
-    $new_role_weights = array();
-    $saved_rids = array();
-
-    // Change the role weights to make the roles in reverse order.
-    $edit = array();
-    foreach ($roles as $role) {
-      $edit['roles['. $role->id() .'][weight]'] =  $weight;
-      $new_role_weights[$role->id()] = $weight;
-      $saved_rids[] = $role->id;
-      $weight--;
-    }
+
+    // Pick up a random role and get its weight.
+    $rid = array_rand(user_roles());
+    $role = user_role_load($rid);
+    $old_weight = $role->weight;
+
+    // Change the role weight and submit the form.
+    $edit = array('roles['. $rid .'][weight]' => $old_weight + 1);
     $this->drupalPost('admin/people/roles', $edit, t('Save order'));
     $this->assertText(t('The role settings have been updated.'), 'The role settings form submitted successfully.');
 
-    // Load up the user roles with the new weights.
-    drupal_static_reset('user_roles');
-    $roles = user_roles();
-    $rids = array();
-    // Test that the role weights have been correctly saved.
-    foreach ($roles as $role) {
-      $this->assertEqual($role->weight, $new_role_weights[$role->id()]);
-      $rids[] = $role->id;
-    }
-    // The order of the roles should be reversed.
-    $this->assertIdentical($rids, array_reverse($saved_rids));
+    // Retrieve the saved role and compare its weight.
+    $role = user_role_load($rid);
+    $new_weight = $role->weight;
+    $this->assertTrue(($old_weight + 1) == $new_weight, 'Role weight updated successfully.');
   }
 }
diff --git a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php b/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php
deleted file mode 100644
index f85d7faab5e8142d4ac58630b6abcb1eec48df29..0000000000000000000000000000000000000000
--- a/core/modules/user/lib/Drupal/user/Tests/Views/HandlerFieldRoleTest.php
+++ /dev/null
@@ -1,60 +0,0 @@
-<?php
-
-/**
- * @file
- * Contains Drupal\user\Tests\Views\HandlerFieldRoleTest.
- */
-
-namespace Drupal\user\Tests\Views;
-
-/**
- * Tests the role field handler.
- *
- * @see views_handler_field_user_name
- */
-class HandlerFieldRoleTest extends UserTestBase {
-
-  /**
-   * Views used by this test.
-   *
-   * @var array
-   */
-  public static $testViews = array('test_views_handler_field_role');
-
-  public static function getInfo() {
-    return array(
-      'name' => 'User: Role Field',
-      'description' => 'Tests the handler of the user: role field.',
-      'group' => 'Views Modules',
-    );
-  }
-
-  public function testRole() {
-    // Create a couple of roles for the view.
-    $rolename_a = 'a' . $this->randomName(8);
-    $rid_a = $this->drupalCreateRole(array('access content'), $rolename_a, $rolename_a, 9);
-
-    $rolename_b = 'b' . $this->randomName(8);
-    $rid_b = $this->drupalCreateRole(array('access content'), $rolename_b, $rolename_b, 8);
-
-    $rolename_not_assigned = $this->randomName(8);
-    $this->drupalCreateRole(array('access content'), $rolename_not_assigned, $rolename_not_assigned);
-
-    // Add roles to user 1.
-    $user = user_load(1);
-    $user->roles[$rid_a] = $rolename_a;
-    $user->roles[$rid_b] = $rolename_b;
-    $user->save();
-
-    $view = views_get_view('test_views_handler_field_role');
-    $this->executeView($view);
-    $view->row_index = 0;
-    // The role field is populated during pre_render.
-    $view->field['rid']->pre_render($view->result);
-    $render = $view->field['rid']->advanced_render($view->result[0]);
-
-    $this->assertEqual($rolename_b . $rolename_a, $render, 'View test_views_handler_field_role renders role assigned to user in the correct order.');
-    $this->assertFalse(strpos($render, $rolename_not_assigned), 'View test_views_handler_field_role does not render a role not assigned to a user.');
-  }
-
-}
diff --git a/core/modules/user/lib/Drupal/user/UserStorageController.php b/core/modules/user/lib/Drupal/user/UserStorageController.php
index 3d8e981548af7aa9ce9f443d105fac9c215dbd91..5d7b634a0f644495ac38ef78f43e5502f5b14437 100644
--- a/core/modules/user/lib/Drupal/user/UserStorageController.php
+++ b/core/modules/user/lib/Drupal/user/UserStorageController.php
@@ -34,9 +34,9 @@ function attachLoad(&$queried_users, $load_revision = FALSE) {
     }
 
     // Add any additional roles from the database.
-    $result = db_query('SELECT rid, uid FROM {users_roles} WHERE uid IN (:uids)', array(':uids' => array_keys($queried_users)));
+    $result = db_query('SELECT r.rid, r.name, ur.uid FROM {role} r INNER JOIN {users_roles} ur ON ur.rid = r.rid WHERE ur.uid IN (:uids)', array(':uids' => array_keys($queried_users)));
     foreach ($result as $record) {
-      $queried_users[$record->uid]->roles[$record->rid] = $record->rid;
+      $queried_users[$record->uid]->roles[$record->rid] = $record->name;
     }
 
     // Call the default attachLoad() method. This will add fields and call
diff --git a/core/modules/user/tests/user_test_views/test_views/views.view.test_views_handler_field_role.yml b/core/modules/user/tests/user_test_views/test_views/views.view.test_views_handler_field_role.yml
deleted file mode 100644
index 8cb9b7a1c61cdfd7f790714e6d46748dfac0cd8c..0000000000000000000000000000000000000000
--- a/core/modules/user/tests/user_test_views/test_views/views.view.test_views_handler_field_role.yml
+++ /dev/null
@@ -1,154 +0,0 @@
-api_version: '3.0'
-base_field: uid
-base_table: users
-core: 8.x
-description: ''
-disabled: '0'
-display:
-  default:
-    display_plugin: default
-    id: default
-    display_title: Master
-    position: ''
-    display_options:
-      access:
-        type: perm
-        perm: 'access user profiles'
-      cache:
-        type: none
-      query:
-        type: views_query
-      exposed_form:
-        type: basic
-      pager:
-        type: none
-        options:
-          items_per_page: ''
-      style:
-        type: default
-      row:
-        type: fields
-      fields:
-        name:
-          id: name
-          table: users
-          field: name
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Name
-          exclude: '0'
-          alter:
-            alter_text: '0'
-            text: ''
-            make_link: '0'
-            path: ''
-            absolute: '0'
-            external: '0'
-            replace_spaces: '0'
-            path_case: none
-            trim_whitespace: '0'
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: '0'
-            max_length: ''
-            word_boundary: '1'
-            ellipsis: '1'
-            more_link: '0'
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: '0'
-            trim: '0'
-            preserve_tags: ''
-            html: '0'
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: '1'
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: '1'
-          empty: ''
-          hide_empty: '0'
-          empty_zero: '0'
-          hide_alter_empty: '1'
-          link_to_user: '1'
-          overwrite_anonymous: '0'
-          anonymous_text: ''
-          format_username: '1'
-        rid:
-          id: rid
-          table: users_roles
-          field: rid
-          relationship: none
-          group_type: group
-          admin_label: ''
-          label: Roles
-          exclude: '0'
-          alter:
-            alter_text: '0'
-            text: ''
-            make_link: '0'
-            path: ''
-            absolute: '0'
-            external: '0'
-            replace_spaces: '0'
-            path_case: none
-            trim_whitespace: '0'
-            alt: ''
-            rel: ''
-            link_class: ''
-            prefix: ''
-            suffix: ''
-            target: ''
-            nl2br: '0'
-            max_length: ''
-            word_boundary: '1'
-            ellipsis: '1'
-            more_link: '0'
-            more_link_text: ''
-            more_link_path: ''
-            strip_tags: '0'
-            trim: '0'
-            preserve_tags: ''
-            html: '0'
-          element_type: ''
-          element_class: ''
-          element_label_type: ''
-          element_label_class: ''
-          element_label_colon: '1'
-          element_wrapper_type: ''
-          element_wrapper_class: ''
-          element_default_classes: '1'
-          empty: ''
-          hide_empty: '0'
-          empty_zero: '0'
-          hide_alter_empty: '1'
-          type: separator
-          separator: ''
-      filters:
-        status:
-          value: '1'
-          table: users
-          field: status
-          id: status
-          expose:
-            operator: '0'
-          group: '1'
-      sorts: {  }
-      title: test_user_role
-  page_1:
-    display_plugin: page
-    id: page_1
-    display_title: Page
-    position: ''
-    display_options:
-      path: test-views-handler-field-role
-human_name: test_views_handler_field_role
-name: test_views_handler_field_role
-tag: ''
diff --git a/core/modules/user/user.admin.inc b/core/modules/user/user.admin.inc
index 1b4d5b0d262eb5447be4dc4a74d6b1b488689871..1689f6210b0f3709a182f3621060eb85b42d9ec3 100644
--- a/core/modules/user/user.admin.inc
+++ b/core/modules/user/user.admin.inc
@@ -208,7 +208,7 @@ function user_admin_account() {
 
   $destination = drupal_get_destination();
   $status = array(t('blocked'), t('active'));
-  $roles = array_map('check_plain', user_role_names(TRUE));
+  $roles = array_map('check_plain', user_roles(TRUE));
   $accounts = array();
   foreach ($result as $account) {
     $account = user_load($account->uid);
@@ -316,7 +316,7 @@ function user_admin_settings($form, &$form_state) {
 
   // Do not allow users to set the anonymous or authenticated user roles as the
   // administrator role.
-  $roles = user_role_names();
+  $roles = user_roles();
   unset($roles[DRUPAL_ANONYMOUS_RID]);
   unset($roles[DRUPAL_AUTHENTICATED_RID]);
   $roles[0] = t('disabled');
@@ -656,7 +656,7 @@ function user_admin_settings_submit($form, &$form_state) {
 function user_admin_permissions($form, $form_state, $rid = NULL) {
 
   // Retrieve role names for columns.
-  $role_names = user_role_names();
+  $role_names = user_roles();
   if (isset($rid)) {
     $role_names = array($rid => $role_names[$rid]);
   }
@@ -757,7 +757,7 @@ function user_admin_permissions_submit($form, &$form_state) {
 function theme_user_admin_permissions($variables) {
   $form = $variables['form'];
 
-  $roles = user_role_names();
+  $roles = user_roles();
   foreach (element_children($form['permission']) as $key) {
     $row = array();
     // Module name
@@ -826,21 +826,27 @@ function theme_user_permission_description($variables) {
  * @see theme_user_admin_roles()
  */
 function user_admin_roles($form, $form_state) {
-  $roles = user_roles();
+  $roles = db_select('role', 'r')
+    ->addTag('translatable')
+    ->fields('r')
+    ->orderBy('weight')
+    ->orderBy('name')
+    ->execute();
 
   $form['roles'] = array(
     '#tree' => TRUE,
   );
-
-  foreach ($roles as $rid => $role) {
-    $form['roles'][$rid]['#role'] = $role;
-    $form['roles'][$rid]['#weight'] = $role->weight;
-    $form['roles'][$rid]['name'] = array(
-      '#markup' => check_plain($role->label()),
+  $max_weight = 0;
+  foreach ($roles as $role) {
+    $max_weight = max($max_weight, $role->weight);
+    $form['roles'][$role->rid]['#role'] = $role;
+    $form['roles'][$role->rid]['#weight'] = $role->weight;
+    $form['roles'][$role->rid]['name'] = array(
+      '#markup' => check_plain($role->name),
     );
-    $form['roles'][$rid]['weight'] = array(
+    $form['roles'][$role->rid]['weight'] = array(
       '#type' => 'textfield',
-      '#title' => t('Weight for @title', array('@title' => $role->label())),
+      '#title' => t('Weight for @title', array('@title' => $role->name)),
       '#title_display' => 'invisible',
       '#size' => 4,
       '#default_value' => $role->weight,
@@ -848,25 +854,26 @@ function user_admin_roles($form, $form_state) {
     );
     $links['edit'] = array(
       'title' => t('edit role'),
-      'href' => 'admin/people/roles/edit/' . $rid,
+      'href' => 'admin/people/roles/edit/' . $role->rid,
       'weight' => 0,
     );
     $links['permissions'] = array(
       'title' => t('edit permissions'),
-      'href' => 'admin/people/permissions/' . $rid,
+      'href' => 'admin/people/permissions/' . $role->rid,
       'weight' => 5,
     );
-    $form['roles'][$rid]['operations'] = array(
+    $form['roles'][$role->rid]['operations'] = array(
       '#type' => 'operations',
       '#links' => $links,
     );
   }
 
   // Embed the role add form.
-  $add_role = entity_create('user_role', array(
-    'id' => NULL,
-    'label' => NULL,
-  ));
+  $add_role = (object) array(
+    'rid' => NULL,
+    'name' => NULL,
+    'weight' => $max_weight + 1,
+  );
   $add_form = user_admin_role(array(), $form_state, $add_role);
   $add_form['actions']['submit']['#submit'] = array('user_admin_role_submit');
   $add_form['role']['actions'] = $add_form['actions'];
@@ -892,7 +899,7 @@ function user_admin_roles_order_submit($form, &$form_state) {
   foreach ($form_state['values']['roles'] as $rid => $role_values) {
     $role = $form['roles'][$rid]['#role'];
     $role->weight = $role_values['weight'];
-    $role->save();
+    user_role_save($role);
   }
   drupal_set_message(t('The role settings have been updated.'));
 }
@@ -946,33 +953,32 @@ function theme_user_admin_roles($variables) {
  *
  * @ingroup forms
  * @see user_admin_role_submit()
- *
- * @todo Move into a RoleFormController.
  */
 function user_admin_role($form, $form_state, $role) {
   $form['role'] = array(
     '#tree' => TRUE,
     '#parents' => array('role'),
   );
-  $form['role']['label'] = array(
+
+  $form['role']['name'] = array(
     '#type' => 'textfield',
     '#title' => t('Role name'),
-    '#default_value' => $role->label(),
+    '#default_value' => $role->name,
     '#size' => 30,
     '#required' => TRUE,
     '#maxlength' => 64,
     '#description' => t('The name for this role. Example: "Moderator", "Editorial board", "Site architect".'),
   );
-  $form['role']['id'] = array(
+  $form['role']['rid'] = array(
     '#type' => 'machine_name',
-    '#default_value' => $role->id(),
+    '#default_value' => $role->rid,
     '#required' => TRUE,
-    '#disabled' => !$role->isNew(),
+    '#disabled' => !empty($role->rid),
     '#size' => 30,
     '#maxlength' => 64,
     '#machine_name' => array(
       'exists' => 'user_role_load',
-      'source' => array('role', 'label'),
+      'source' => array('role', 'name'),
     ),
   );
   $form['role']['weight'] = array(
@@ -982,12 +988,12 @@ function user_admin_role($form, $form_state, $role) {
   $form['actions'] = array('#type' => 'actions');
   $form['actions']['submit'] = array(
     '#type' => 'submit',
-    '#value' => !$role->isNew() ? t('Save role') : t('Add role'),
+    '#value' => !empty($role->rid) ? t('Save role') : t('Add role'),
   );
   $form['actions']['delete'] = array(
     '#type' => 'submit',
     '#value' => t('Delete role'),
-    '#access' => !$role->isNew() && !in_array($role->id(), array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)),
+    '#access' => !empty($role->rid) && !in_array($role->rid, array(DRUPAL_ANONYMOUS_RID, DRUPAL_AUTHENTICATED_RID)),
     '#submit' => array('user_admin_role_delete_submit'),
   );
 
@@ -998,11 +1004,9 @@ function user_admin_role($form, $form_state, $role) {
  * Form submit handler for the user_admin_role() form.
  */
 function user_admin_role_submit($form, &$form_state) {
-  // Prevent leading and trailing spaces in role names.
-  $form_state['values']['role']['label'] = trim($form_state['values']['role']['label']);
-
-  $role = entity_create('user_role', $form_state['values']['role']);
-  if ($role->save() == SAVED_UPDATED) {
+  $role = (object) $form_state['values']['role'];
+  $status = user_role_save($role);
+  if ($status === SAVED_UPDATED) {
     drupal_set_message(t('The role has been renamed.'));
   }
   else {
@@ -1015,25 +1019,26 @@ function user_admin_role_submit($form, &$form_state) {
  * Form submit handler for the user_admin_role() form.
  */
 function user_admin_role_delete_submit($form, &$form_state) {
-  $form_state['redirect'] = 'admin/people/roles/delete/' . $form_state['values']['role']['id'];
+  $form_state['redirect'] = 'admin/people/roles/delete/' . $form_state['values']['role']['rid'];
 }
 
 /**
  * Form to confirm role delete operation.
  */
 function user_admin_role_delete_confirm($form, &$form_state, $role) {
-  $form['id'] = array(
+  $form['rid'] = array(
     '#type' => 'value',
-    '#value' => $role->id(),
+    '#value' => $role->rid,
   );
-  return confirm_form($form, t('Are you sure you want to delete the role %name ?', array('%name' => $role->label())), 'admin/people/roles', t('This action cannot be undone.'), t('Delete'));
+  return confirm_form($form, t('Are you sure you want to delete the role %name ?', array('%name' => $role->name)), 'admin/people/roles', t('This action cannot be undone.'), t('Delete'));
 }
 
 /**
  * Form submit handler for user_admin_role_delete_confirm().
  */
 function user_admin_role_delete_confirm_submit($form, &$form_state) {
-  entity_delete_multiple('user_role', array($form_state['values']['id']));
+  user_role_delete($form_state['values']['rid']);
   drupal_set_message(t('The role has been deleted.'));
   $form_state['redirect'] = 'admin/people/roles';
 }
+
diff --git a/core/modules/user/user.api.php b/core/modules/user/user.api.php
index 652c5b5772adeaf92547e12daca890d8e1a7a5b1..cae3ddec91af65348d3607ed98b10ace22319097 100644
--- a/core/modules/user/user.api.php
+++ b/core/modules/user/user.api.php
@@ -440,7 +440,7 @@ function hook_user_role_insert($role) {
   // Save extra fields provided by the module to user roles.
   db_insert('my_module_table')
     ->fields(array(
-      'rid' => $role->id(),
+      'rid' => $role->rid,
       'role_description' => $role->description,
     ))
     ->execute();
@@ -460,7 +460,7 @@ function hook_user_role_insert($role) {
 function hook_user_role_update($role) {
   // Save extra fields provided by the module to user roles.
   db_merge('my_module_table')
-    ->key(array('rid' => $role->id()))
+    ->key(array('rid' => $role->rid))
     ->fields(array(
       'role_description' => $role->description
     ))
@@ -481,7 +481,7 @@ function hook_user_role_update($role) {
 function hook_user_role_delete($role) {
   // Delete existing instances of the deleted role.
   db_delete('my_module_table')
-    ->condition('rid', $role->id())
+    ->condition('rid', $role->rid)
     ->execute();
 }
 
diff --git a/core/modules/user/user.install b/core/modules/user/user.install
index ff5a0e2ed67fcb5824d53fe27c4f17fe91f9ab31..92febf44b18a319c923c8074e2f9b2832a05fed2 100644
--- a/core/modules/user/user.install
+++ b/core/modules/user/user.install
@@ -148,6 +148,39 @@ function user_schema() {
     ),
   );
 
+  $schema['role'] = array(
+    'description' => 'Stores user roles.',
+    'fields' => array(
+      'rid' => array(
+        'type' => 'varchar',
+        // The role ID is often used as part of a compound index; at least MySQL
+        // has a maximum index length of 1000 characters (333 on utf8), so we
+        // limit the maximum length.
+        'length' => 64,
+        'not null' => TRUE,
+        'description' => 'Primary Key: Unique role ID.',
+      ),
+      'name' => array(
+        'type' => 'varchar',
+        'length' => 255,
+        'not null' => TRUE,
+        'default' => '',
+        'description' => 'Role label.',
+        'translatable' => TRUE,
+      ),
+      'weight' => array(
+        'type' => 'int',
+        'not null' => TRUE,
+        'default' => 0,
+        'description' => 'The weight of this role in listings and the user interface.',
+      ),
+    ),
+    'primary key' => array('rid'),
+    'indexes' => array(
+      'name_weight' => array('name', 'weight'),
+    ),
+  );
+
   $schema['role_permission'] = array(
     'description' => 'Stores the permissions assigned to user roles.',
     'fields' => array(
@@ -293,6 +326,13 @@ function user_install() {
       'status' => 1,
     ))
     ->execute();
+
+  // Insert built-in roles.
+  db_insert('role')
+    ->fields(array('rid', 'name', 'weight'))
+    ->values(array(DRUPAL_ANONYMOUS_RID, 'Anonymous user', 0))
+    ->values(array(DRUPAL_AUTHENTICATED_RID, 'Authenticated user', 1))
+    ->execute();
 }
 
 /**
@@ -1014,34 +1054,6 @@ function user_update_8016() {
   db_drop_field('users', 'data');
 }
 
-/**
- * Migrate user roles into configuration.
- *
- * @ingroup config_upgrade
- */
-function user_update_8017() {
-  $uuid = new Uuid();
-
-  $roles = db_select('role', 'r')
-    ->fields('r')
-    ->execute()
-    ->fetchAll();
-
-  foreach ($roles as $role) {
-    config('user.role.' . $role->rid)
-      ->set('id', $role->rid)
-      ->set('uuid', $uuid->generate())
-      ->set('label', $role->name)
-      ->set('weight', $role->weight)
-      ->set('langcode', LANGUAGE_NOT_SPECIFIED)
-      ->save();
-  }
-
-  update_config_manifest_add('user.role', array_map(function ($role) {
-    return $role->rid;
-  }, $roles));
-}
-
 /**
  * @} End of "addtogroup updates-7.x-to-8.x".
  */
diff --git a/core/modules/user/user.module b/core/modules/user/user.module
index 89bc6c1675316c502c54d3253f25682cb588ab82..3082cde39d8e88e4e3e09526f296134ed9ed2254 100644
--- a/core/modules/user/user.module
+++ b/core/modules/user/user.module
@@ -6,7 +6,6 @@
 use Drupal\entity\Plugin\Core\Entity\EntityDisplay;
 use Drupal\file\Plugin\Core\Entity\File;
 use Drupal\user\Plugin\Core\Entity\User;
-use Drupal\user\UserRole;
 use Drupal\Core\Template\Attribute;
 use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
 
@@ -1819,25 +1818,6 @@ function user_mail_tokens(&$replacements, $data, $options) {
  *   An associative array with the role id as the key and the role name as
  *   value.
  */
-function user_role_names($membersonly = FALSE, $permission = NULL) {
-  return array_map(function($item) {
-    return $item->label();
-  }, user_roles($membersonly, $permission));
-}
-
-/**
- * Retrieve an array of roles matching specified conditions.
- *
- * @param $membersonly
- *   Set this to TRUE to exclude the 'anonymous' role.
- * @param $permission
- *   A string containing a permission. If set, only roles containing that
- *   permission are returned.
- *
- * @return
- *   An associative array with the role id as the key and the role object as
- *   value.
- */
 function user_roles($membersonly = FALSE, $permission = NULL) {
   $user_roles = &drupal_static(__FUNCTION__);
 
@@ -1850,22 +1830,23 @@ function user_roles($membersonly = FALSE, $permission = NULL) {
     }
   }
 
-  $roles = entity_load_multiple('user_role');
-  if ($membersonly) {
-    unset($roles[DRUPAL_ANONYMOUS_RID]);
-  }
-
+  $query = db_select('role', 'r');
+  $query->addTag('translatable');
+  $query->fields('r', array('rid', 'name'));
+  $query->orderBy('weight');
+  $query->orderBy('name');
   if (!empty($permission)) {
-    $result = db_select('role_permission', 'p')
-      ->fields('p', array('rid'))
-      ->condition('p.rid', array_keys($roles))
-      ->condition('p.permission', $permission)
-      ->execute()->fetchCol();
-    $roles = array_intersect_key($roles, array_flip($result));
+    $query->innerJoin('role_permission', 'p', 'r.rid = p.rid');
+    $query->condition('p.permission', $permission);
+  }
+  if ($membersonly) {
+    $query->condition('r.rid', DRUPAL_ANONYMOUS_RID, '!=');
   }
+  $roles = $query->execute()->fetchAllKeyed();
 
   if (empty($permission)) {
     $user_roles[$cid] = $roles;
+    return $user_roles[$cid];
   }
 
   return $roles;
@@ -1882,7 +1863,87 @@ function user_roles($membersonly = FALSE, $permission = NULL) {
  *   otherwise.
  */
 function user_role_load($rid) {
-  return entity_load('user_role', $rid);
+  return db_select('role', 'r')
+    ->fields('r')
+    ->condition('rid', $rid)
+    ->execute()
+    ->fetchObject();
+}
+
+/**
+ * Save a user role to the database.
+ *
+ * @param $role
+ *   A role object to modify or add.
+ *
+ * @return
+ *   Status constant indicating if role was created or updated.
+ *   Failure to write the user role record will return FALSE. Otherwise
+ *   SAVED_NEW or SAVED_UPDATED is returned depending on the operation
+ *   performed.
+ */
+function user_role_save($role) {
+  if ($role->name) {
+    // Prevent leading and trailing spaces in role names.
+    $role->name = trim($role->name);
+  }
+  if (!isset($role->weight)) {
+    // Set a role weight to make this new role last.
+    $query = db_select('role');
+    $query->addExpression('MAX(weight)');
+    $role->weight = $query->execute()->fetchField() + 1;
+  }
+
+  // Let modules modify the user role before it is saved to the database.
+  module_invoke_all('user_role_presave', $role);
+
+  $exists = db_select('role', 'r')
+    ->fields('r', array('rid'))
+    ->condition('rid', $role->rid)
+    ->execute()
+    ->fetchAll();
+
+  if (empty($exists)) {
+    $status = drupal_write_record('role', $role);
+    module_invoke_all('user_role_insert', $role);
+  }
+  else {
+    $status = drupal_write_record('role', $role, 'rid');
+    module_invoke_all('user_role_update', $role);
+  }
+
+  // Clear the user access cache.
+  drupal_static_reset('user_access');
+  drupal_static_reset('user_role_permissions');
+
+  return $status;
+}
+
+/**
+ * Delete a user role from database.
+ *
+ * @param $role
+ *   A string with the role ID.
+ */
+function user_role_delete($role) {
+  $role = user_role_load($role);
+
+  db_delete('role')
+    ->condition('rid', $role->rid)
+    ->execute();
+  db_delete('role_permission')
+    ->condition('rid', $role->rid)
+    ->execute();
+  // Update the users who have this role set:
+  db_delete('users_roles')
+    ->condition('rid', $role->rid)
+    ->execute();
+
+  module_invoke_all('user_role_delete', $role);
+
+  // Clear the user access cache.
+  drupal_static_reset('user_access');
+  drupal_static_reset('user_role_permissions');
 }
 
 /**
@@ -1890,7 +1951,7 @@ function user_role_load($rid) {
  */
 function user_role_delete_access($role) {
   // Prevent the system-defined roles from being removed.
-  if ($role->id() == DRUPAL_ANONYMOUS_RID || $role->id() == DRUPAL_AUTHENTICATED_RID) {
+  if ($role->rid == DRUPAL_ANONYMOUS_RID || $role->rid == DRUPAL_AUTHENTICATED_RID) {
     return FALSE;
   }
 
@@ -2029,7 +2090,7 @@ function user_user_operations($form = array(), $form_state = array()) {
   );
 
   if (user_access('administer permissions')) {
-    $roles = user_role_names(TRUE);
+    $roles = user_roles(TRUE);
     unset($roles[DRUPAL_AUTHENTICATED_RID]);  // Can't edit authenticated role.
 
     $add_roles = array();
@@ -2114,7 +2175,7 @@ function user_user_operations_block($accounts) {
  * Callback function for admin mass adding/deleting a user role.
  */
 function user_multiple_role_edit($accounts, $operation, $rid) {
-  $role_name = entity_load('user_role', $rid)->label();
+  $role_name = db_query('SELECT name FROM {role} WHERE rid = :rid', array(':rid' => $rid))->fetchField();
 
   switch ($operation) {
     case 'add_role':
@@ -2246,7 +2307,7 @@ function user_multiple_cancel_confirm_submit($form, &$form_state) {
 function user_filters() {
   // Regular filters
   $filters = array();
-  $roles = user_role_names(TRUE);
+  $roles = user_roles(TRUE);
   unset($roles[DRUPAL_AUTHENTICATED_RID]); // Don't list authorized role.
   if (count($roles)) {
     $filters['role'] = array(
diff --git a/core/modules/user/user.views.inc b/core/modules/user/user.views.inc
index 868c3ab478351392be343a8e726af31d4ad5f4c9..9264381130591a43848cb4af27cb8ae786212dfd 100644
--- a/core/modules/user/user.views.inc
+++ b/core/modules/user/user.views.inc
@@ -351,6 +351,22 @@ function user_views_data() {
     ),
   );
 
+  // role table
+
+  $data['role']['table']['join'] = array(
+     // Directly links to users table.
+    'users' => array(
+      'left_table' => 'users_roles',
+      'left_field' => 'rid',
+      'field' => 'rid',
+    ),
+    // needed for many to one helper sometimes
+    'users_roles' => array(
+      'left_field' => 'rid',
+      'field' => 'rid',
+    ),
+  );
+
   // permission table
   $data['role_permission']['table']['group']  = t('User');
   $data['role_permission']['table']['join'] = array(
diff --git a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
index b737cc7a8aed7b679ac484728f545b1733607d44..fbd618415acad5147a8d48d312b7fb9deaea7166 100644
--- a/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
+++ b/core/modules/views/lib/Drupal/views/Plugin/views/filter/FilterPluginBase.php
@@ -551,7 +551,7 @@ public function buildExposeForm(&$form, &$form_state) {
       '#default_value' => $this->options['expose']['remember'],
     );
 
-    $role_options = array_map('check_plain', user_role_names());
+    $role_options = array_map('check_plain', user_roles());
     $form['expose']['remember_roles'] = array(
       '#type' => 'checkboxes',
       '#title' => t('User roles'),
diff --git a/core/profiles/standard/config/user.role.administrator.yml b/core/profiles/standard/config/user.role.administrator.yml
deleted file mode 100644
index 71187f9280512f915545fd46c181297e1cd9b533..0000000000000000000000000000000000000000
--- a/core/profiles/standard/config/user.role.administrator.yml
+++ /dev/null
@@ -1,3 +0,0 @@
-id: administrator
-label: Administrator
-weight: 2
diff --git a/core/profiles/standard/standard.install b/core/profiles/standard/standard.install
index 8802bbc6a89adb06512c41eeee05a16f97571b0b..4d464ccd056f9f2795c9f21e04246b1ec9c92821 100644
--- a/core/profiles/standard/standard.install
+++ b/core/profiles/standard/standard.install
@@ -225,14 +225,19 @@ function standard_install() {
   user_role_grant_permissions(DRUPAL_ANONYMOUS_RID, array('access content', 'access comments'));
   user_role_grant_permissions(DRUPAL_AUTHENTICATED_RID, array('access content', 'access comments', 'post comments', 'skip comment approval'));
 
-  // Enable all permissions for the administrator role.
-  user_role_grant_permissions('administrator', array_keys(module_invoke_all('permission')));
+  // Create a default role for site administrators, with all available permissions assigned.
+  $admin_role = new stdClass();
+  $admin_role->rid = 'administrator';
+  $admin_role->name = 'Administrator';
+  $admin_role->weight = 2;
+  user_role_save($admin_role);
+  user_role_grant_permissions($admin_role->rid, array_keys(module_invoke_all('permission')));
   // Set this as the administrator role.
-  $user_settings->set('admin_role', 'administrator')->save();
+  $user_settings->set('admin_role', $admin_role->rid)->save();
 
   // Assign user 1 the "administrator" role.
   db_insert('users_roles')
-    ->fields(array('uid' => 1, 'rid' => 'administrator'))
+    ->fields(array('uid' => 1, 'rid' => $admin_role->rid))
     ->execute();
 
   // Create a Home link in the main menu.