Index: includes/theme.inc
===================================================================
RCS file: /cvs/drupal/drupal/includes/theme.inc,v
retrieving revision 1.533
diff -u -p -r1.533 theme.inc
--- includes/theme.inc	9 Oct 2009 16:33:13 -0000	1.533
+++ includes/theme.inc	11 Oct 2009 19:16:41 -0000
@@ -779,25 +779,43 @@ function theme($hook, $variables = array
   }
 
   // If a renderable array is passed as $variables, then set $variables to
-  // what's expected by the theme hook. If the theme hook expects a single
-  // argument, set the renderable array as that argument. If the theme hook
-  // expects multiple arguments, set the properties of the renderable array as
-  // those arguments.
+  // what's expected by the theme hook. If the theme hook expects multiple
+  // arguments, use the properties of the renderable array as those arguments.
+  // If the theme hook expects a single argument, make a best guess as to
+  // whether the theme hook wants the renderable array itself or its property
+  // as that argument.
+  // @todo: For Drupal 8, fix it so that guessing isn't necessary.
   if (isset($variables['#theme']) || isset($variables['#theme_wrappers'])) {
     $element = $variables;
     $variables = array();
     $n = count($info['arguments']);
-    if ($n == 1) {
-      $arg_keys = array_keys($info['arguments']);
-      $variables[$arg_keys[0]] = $element;
-    }
-    elseif ($n > 1) {
-      foreach ($info['arguments'] as $name => $default) {
+    $arg_keys = array_keys($info['arguments']);
+    // All theme hooks designed to be passed a renderable element from
+    // drupal_render() have just that one argument, so it's safe to assume
+    // that a multiple argument theme hook wants the properties of the element
+    // and not the element. The majority of 1 argument theme hooks expect the
+    // element, but there are still some 1 argument theme hooks that don't
+    // expect a renderable element, but that are still sometimes invoked via
+    // drupal_render(), and need to receive the element's property as the
+    // argument. Given this, we want to lean towards assuming the element is
+    // wanted, and only assume otherwise if the element DOES NOT have a type AND
+    // DOES have a property matching the argument name expected by the theme
+    // hook. This means that a 1-argument theme hook invoked via drupal_render()
+    // that needs to have its argument come from the element's property must
+    // have that property set on the element AND may not have the 'type'
+    // property set. If this condition doesn't work for a particular theme hook,
+    // refactor it to use a renderable array as its argument.
+    // @see http://drupal.org/node/600974
+    if ($n > 1 || (!isset($element['#type']) && isset($element['#' . $arg_keys[0]]))) {
+      foreach ($arg_keys as $name) {
         if (isset($element["#$name"])) {
           $variables[$name] = $element["#$name"];
         }
       }
     }
+    else {
+      $variables[$arg_keys[0]] = $element;
+    }
   }
 
   // Merge in argument defaults.
