diff --git a/core/includes/form.inc b/core/includes/form.inc
index 5d4a943..014c246 100644
--- a/core/includes/form.inc
+++ b/core/includes/form.inc
@@ -579,42 +579,6 @@ function form_type_radios_value(&$element, $input = FALSE) {
 }
 
 /**
- * Determines the value for a tableselect form element.
- *
- * @param $element
- *   The form element whose value is being populated.
- * @param $input
- *   The incoming input to populate the form element. If this is FALSE,
- *   the element's default value should be returned.
- *
- * @return
- *   The data that will appear in the $element_state['values'] collection
- *   for this element. Return nothing to use the default.
- */
-function form_type_tableselect_value($element, $input = FALSE) {
-  // If $element['#multiple'] == FALSE, then radio buttons are displayed and
-  // the default value handling is used.
-  if (isset($element['#multiple']) && $element['#multiple']) {
-    // Checkboxes are being displayed with the default value coming from the
-    // keys of the #default_value property. This differs from the checkboxes
-    // element which uses the array values.
-    if ($input === FALSE) {
-      $value = array();
-      $element += array('#default_value' => array());
-      foreach ($element['#default_value'] as $key => $flag) {
-        if ($flag) {
-          $value[$key] = $key;
-        }
-      }
-      return $value;
-    }
-    else {
-      return is_array($input) ? drupal_map_assoc($input) : array();
-    }
-  }
-}
-
-/**
  * Determines the value for a password_confirm form element.
  *
  * @param $element
@@ -1484,177 +1448,6 @@ function form_process_container($element, &$form_state) {
 }
 
 /**
- * Returns HTML for a table with radio buttons or checkboxes.
- *
- * @param $variables
- *   An associative array containing:
- *   - element: An associative array containing the properties and children of
- *     the tableselect element. Properties used: #header, #options, #empty,
- *     and #js_select. The #options property is an array of selection options;
- *     each array element of #options is an array of properties. These
- *     properties can include #attributes, which is added to the
- *     table row's HTML attributes; see theme_table(). An example of per-row
- *     options:
- *     @code
- *     $options = array(
- *       array(
- *         'title' => 'How to Learn Drupal',
- *         'content_type' => 'Article',
- *         'status' => 'published',
- *         '#attributes' => array('class' => array('article-row')),
- *       ),
- *       array(
- *         'title' => 'Privacy Policy',
- *         'content_type' => 'Page',
- *         'status' => 'published',
- *         '#attributes' => array('class' => array('page-row')),
- *       ),
- *     );
- *     $header = array(
- *       'title' => t('Title'),
- *       'content_type' => t('Content type'),
- *       'status' => t('Status'),
- *     );
- *     $form['table'] = array(
- *       '#type' => 'tableselect',
- *       '#header' => $header,
- *       '#options' => $options,
- *       '#empty' => t('No content available.'),
- *     );
- *     @endcode
- *
- * @ingroup themeable
- */
-function theme_tableselect($variables) {
-  $element = $variables['element'];
-  $rows = array();
-  $header = $element['#header'];
-  if (!empty($element['#options'])) {
-    // Generate a table row for each selectable item in #options.
-    foreach (element_children($element) as $key) {
-      $row = array();
-
-      $row['data'] = array();
-      if (isset($element['#options'][$key]['#attributes'])) {
-        $row += $element['#options'][$key]['#attributes'];
-      }
-      // Render the checkbox / radio element.
-      $row['data'][] = drupal_render($element[$key]);
-
-      // As theme_table only maps header and row columns by order, create the
-      // correct order by iterating over the header fields.
-      foreach ($element['#header'] as $fieldname => $title) {
-        // A row cell can span over multiple headers, which means less row cells
-        // than headers could be present.
-        if (isset($element['#options'][$key][$fieldname])) {
-          // A header can span over multiple cells and in this case the cells
-          // are passed in an array. The order of this array determines the
-          // order in which they are added.
-          if (!isset($element['#options'][$key][$fieldname]['data']) && is_array($element['#options'][$key][$fieldname])) {
-            foreach ($element['#options'][$key][$fieldname] as $cell) {
-              $row['data'][] = $cell;
-            }
-          }
-          else {
-            $row['data'][] = $element['#options'][$key][$fieldname];
-          }
-        }
-      }
-      $rows[] = $row;
-    }
-    // Add an empty header or a "Select all" checkbox to provide room for the
-    // checkboxes/radios in the first table column.
-    if ($element['#js_select']) {
-      // Add a "Select all" checkbox.
-      drupal_add_library('system', 'drupal.tableselect');
-      array_unshift($header, array('class' => array('select-all')));
-    }
-    else {
-      // Add an empty header when radio buttons are displayed or a "Select all"
-      // checkbox is not desired.
-      array_unshift($header, '');
-    }
-  }
-  return theme('table', array('header' => $header, 'rows' => $rows, 'empty' => $element['#empty'], 'attributes' => $element['#attributes']));
-}
-
-/**
- * Creates checkbox or radio elements to populate a tableselect table.
- *
- * @param $element
- *   An associative array containing the properties and children of the
- *   tableselect element.
- *
- * @return
- *   The processed element.
- */
-function form_process_tableselect($element) {
-
-  if ($element['#multiple']) {
-    $value = is_array($element['#value']) ? $element['#value'] : array();
-  }
-  else {
-    // Advanced selection behavior makes no sense for radios.
-    $element['#js_select'] = FALSE;
-  }
-
-  $element['#tree'] = TRUE;
-
-  if (count($element['#options']) > 0) {
-    if (!isset($element['#default_value']) || $element['#default_value'] === 0) {
-      $element['#default_value'] = array();
-    }
-
-    // Create a checkbox or radio for each item in #options in such a way that
-    // the value of the tableselect element behaves as if it had been of type
-    // checkboxes or radios.
-    foreach ($element['#options'] as $key => $choice) {
-      // Do not overwrite manually created children.
-      if (!isset($element[$key])) {
-        if ($element['#multiple']) {
-          $title = '';
-          if (!empty($element['#options'][$key]['title']['data']['#title'])) {
-            $title = t('Update @title', array(
-              '@title' => $element['#options'][$key]['title']['data']['#title'],
-            ));
-          }
-          $element[$key] = array(
-            '#type' => 'checkbox',
-            '#title' => $title,
-            '#title_display' => 'invisible',
-            '#return_value' => $key,
-            '#default_value' => isset($value[$key]) ? $key : NULL,
-            '#attributes' => $element['#attributes'],
-          );
-        }
-        else {
-          // Generate the parents as the autogenerator does, so we will have a
-          // unique id for each radio button.
-          $parents_for_id = array_merge($element['#parents'], array($key));
-          $element[$key] = array(
-            '#type' => 'radio',
-            '#title' => '',
-            '#return_value' => $key,
-            '#default_value' => ($element['#default_value'] == $key) ? $key : NULL,
-            '#attributes' => $element['#attributes'],
-            '#parents' => $element['#parents'],
-            '#id' => drupal_html_id('edit-' . implode('-', $parents_for_id)),
-            '#ajax' => isset($element['#ajax']) ? $element['#ajax'] : NULL,
-          );
-        }
-        if (isset($element['#options'][$key]['#weight'])) {
-          $element[$key]['#weight'] = $element['#options'][$key]['#weight'];
-        }
-      }
-    }
-  }
-  else {
-    $element['#value'] = array();
-  }
-  return $element;
-}
-
-/**
  * #process callback for #type 'table' to add tableselect support.
  *
  * @param array $element
@@ -1665,9 +1458,6 @@ function form_process_tableselect($element) {
  *
  * @return array
  *   The processed element.
- *
- * @see form_process_tableselect()
- * @see theme_tableselect()
  */
 function form_process_table($element, &$form_state) {
   if ($element['#tableselect']) {
diff --git a/core/includes/theme.inc b/core/includes/theme.inc
index bfd1aaf..5435136 100644
--- a/core/includes/theme.inc
+++ b/core/includes/theme.inc
@@ -2719,9 +2719,6 @@ function drupal_common_theme() {
     'textarea' => array(
       'render element' => 'element',
     ),
-    'tableselect' => array(
-      'render element' => 'element',
-    ),
     'form_element' => array(
       'render element' => 'element',
     ),
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 43d15a6..580e20f 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -1030,7 +1030,7 @@ protected function doValidateForm(&$elements, &$form_state, $form_id = NULL) {
             $options = $elements['#options'];
           }
           if (is_array($elements['#value'])) {
-            $value = in_array($elements['#type'], array('checkboxes', 'tableselect')) ? array_keys($elements['#value']) : $elements['#value'];
+            $value = $elements['#type'] == 'checkboxes' ? array_keys($elements['#value']) : $elements['#value'];
             foreach ($value as $v) {
               if (!isset($options[$v])) {
                 $this->setError($elements, $form_state, $this->t('An illegal choice has been detected. Please contact the site administrator.'));
diff --git a/core/modules/system/system.module b/core/modules/system/system.module
index 295c2f8..0722b13 100644
--- a/core/modules/system/system.module
+++ b/core/modules/system/system.module
@@ -505,15 +505,6 @@ function system_element_info() {
     '#theme' => 'input__file',
     '#theme_wrappers' => array('form_element'),
   );
-  $types['tableselect'] = array(
-    '#input' => TRUE,
-    '#js_select' => TRUE,
-    '#multiple' => TRUE,
-    '#process' => array('form_process_tableselect'),
-    '#options' => array(),
-    '#empty' => '',
-    '#theme' => 'tableselect',
-  );
 
   // Form structure.
   $types['item'] = array(
