Copilot commented on code in PR #3787:
URL: https://github.com/apache/thrift/pull/3787#discussion_r3918106342


##########
compiler/cpp/src/thrift/generate/t_php_generator.cc:
##########
@@ -2681,13 +2681,30 @@ void 
t_php_generator::generate_serialize_container(ostream& out, t_type* ttype,
   } else if (ttype->is_set()) {
     string iter = tmp("iter");
     string iter_val = tmp("iter");
-    indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << 
iter_val << ") {" << '\n';
-    indent_up();
-
     t_type* elem_type = ((t_set*)ttype)->get_elem_type();
-    if(php_is_scalar(elem_type)) {
-      generate_serialize_set_element(out, (t_set*)ttype, iter);
+    if (php_is_scalar(elem_type)) {
+      string set_uses_values = tmp("setUsesValues");
+      string list_val = tmp("iter");
+      string iter_elem = tmp("iter");
+      indent(out) << "$" << set_uses_values << " = false;" << '\n';
+      indent(out) << "if (array_is_list($" << prefix << ")) {" << '\n';
+      indent_up();
+      indent(out) << "foreach ($" << prefix << " as $" << list_val << ") {" << 
'\n';
+      indent_up();
+      indent(out) << "if ($" << list_val << " !== true) {" << '\n';
+      indent_up();
+      indent(out) << "$" << set_uses_values << " = true;" << '\n';
+      indent(out) << "break;" << '\n';
+      scope_down(out);
+      scope_down(out);
+      scope_down(out);
+      indent(out) << "foreach ($" << prefix << " as $" << iter << " => $" << 
iter_val << ") {" << '\n';
+      indent_up();
+      indent(out) << "$" << iter_elem << " = $" << set_uses_values << " ? $" 
<< iter_val << " : $" << iter << ";" << '\n';
+      generate_serialize_set_element(out, (t_set*)ttype, iter_elem);

Review Comment:
   The generated scalar-set serialization uses the same `array_is_list` + “any 
element !== true” heuristic. For `set<bool>`, a sequential values input like 
`[true]` will serialize the key index (`0`) rather than the value (`true`), so 
boolean scalar sets don’t fully benefit from the “accept sequential list” 
compatibility change. Please clarify intended behavior (likely via a 
generator/runtime comment + regression test) to avoid surprising 
inconsistencies.



##########
lib/php/lib/Exception/TException.php:
##########
@@ -348,8 +348,17 @@ private function writeList(array $var, array $spec, 
TProtocol $output, bool $set
         } else {
             $xfer += $output->writeListBegin($etype, count($var));
         }
+        $setUsesValues = false;
+        if ($set && array_is_list($var)) {
+            foreach ($var as $candidate) {
+                if ($candidate !== true) {
+                    $setUsesValues = true;
+                    break;
+                }
+            }
+        }
         foreach ($var as $key => $val) {
-            $elem = $set ? $key : $val;
+            $elem = $set && !$setUsesValues ? $key : $val;

Review Comment:
   Same `set` list-vs-legacy heuristic as in `TBase::writeList`: for 
`set<bool>`, a sequential values input like `[true]` is interpreted as legacy 
marker form (all values are `true`), causing serialization of key `0` (`false`) 
instead of the intended `true`. Please clarify intended semantics for 
`set<bool>` and add a regression test so both `TException` and `TBase` stay 
consistent.



##########
lib/php/lib/Base/TBase.php:
##########
@@ -349,8 +349,17 @@ private function writeList(array $var, array $spec, 
TProtocol $output, bool $set
         } else {
             $xfer += $output->writeListBegin($etype, count($var));
         }
+        $setUsesValues = false;
+        if ($set && array_is_list($var)) {
+            foreach ($var as $candidate) {
+                if ($candidate !== true) {
+                    $setUsesValues = true;
+                    break;
+                }
+            }
+        }
         foreach ($var as $key => $val) {
-            $elem = $set ? $key : $val;
+            $elem = $set && !$setUsesValues ? $key : $val;

Review Comment:
   The list-vs-legacy detection for sets (`array_is_list` + “any value !== 
true”) has an ambiguous/incorrect case for `set<bool>`: a sequential values 
input like `[true]` will be treated as the legacy “key => true marker” form 
(because all values are `true`), so the element serialized becomes the key `0` 
(i.e., `false`) rather than `true`. This means the PR’s stated “accept scalar 
sets provided as sequential lists” does not fully hold for boolean sets unless 
callers use the keyed form `[1 => true]`. Please decide and document the 
intended behavior for `set<bool>` (and add a regression test to lock it in).



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]

Reply via email to