Index: ./drupal/modules/field/modules/list/list.module
===================================================================
RCS file: /cvs/drupal/drupal/modules/field/modules/list/list.module,v
retrieving revision 1.35
diff -u -p -r1.35 list.module
--- ./drupal/modules/field/modules/list/list.module	11 Oct 2010 19:57:00 -0000	1.35
+++ ./drupal/modules/field/modules/list/list.module	14 Oct 2010 21:48:22 -0000
@@ -139,6 +139,33 @@ function list_field_settings_form($field
 }
 
 /**
+ * Implementation of hook_field_update_forbid(
+ */
+function list_field_update_forbid($field, $prior_field, $has_data) {
+
+  // A 'list' field stores integer keys mapped to display values. If
+  // the new field has abandoned keys and data data exists for the
+  // abandoned keys, the field will have no way to display them. So,
+  // forbid such an update.
+  $prior_field_allowed = list_extract_allowed_values($prior_field['settings']['allowed_values'], $prior_field['type'] == 'list');
+  $field_allowed = list_extract_allowed_values($field['settings']['allowed_values'], $field['type'] == 'list');
+  
+  if ($has_data && $lost_keys = array_diff(array_keys($prior_field_allowed), array_keys($field_allowed))) {
+    // If any data exist for those keys, forbid the update.
+    $query = new EntityFieldQuery();
+    $found = $query
+      ->fieldCondition($prior_field['field_name'], 'value', $lost_keys)
+      ->range(0, 1)
+      ->execute();
+    if ($found) {
+      throw new FieldUpdateForbiddenException("Cannot update a list field to remove keys that have existing data");
+    }
+  }
+}
+
+
+
+/**
  * Element validate callback; check that the entered values are valid.
  */
 function list_allowed_values_setting_validate($element, &$form_state) {
@@ -160,6 +187,35 @@ function list_allowed_values_setting_val
       break;
     }
   }
+
+  if (!empty($form_state['values']['field']['field_name'])) {
+    // via manage fields tab
+    $field_name = $form_state['values']['field']['field_name'];
+  }
+  else {
+    // via edit tab
+    $field_name = $form_state['values']['instance']['field_name'];
+  }
+  
+  $prior_field = field_info_field($field_name);
+
+  if (!empty($form_state['values']['field']['type'])) {
+    // via manage fields tab
+    $new_field = $form_state['values']['field'];
+  }
+  else {
+    // via edit tab
+    $new_field = $prior_field;
+    $new_field['settings']['allowed_values'] = $form_state['values']['field']['settings']['allowed_values'];
+  }
+
+  try {
+    list_field_update_forbid($new_field, $prior_field, field_has_data($prior_field));
+  }
+  catch (FieldUpdateForbiddenException $e) {
+    form_error($element, $e->getMessage());
+  }
+  
 }
 
 /**
@@ -242,7 +298,7 @@ function list_extract_allowed_values($st
     }
     // Otherwise see if we need to use the value as the key. The "list" type
     // will automatically convert non-keyed lines to integers.
-    elseif (!$position_keys) {
+    elseif ($position_keys) {
       $key = $value;
     }
     $values[$key] = (isset($value) && $value !== '') ? $value : $key;
