I forgot about this php feature earlier - ... unpacks an traversable, making it implicitly call traversable helpers.
For enums, this should still be a CompileError, but would be more useful to make the error message Cannot unpack enums in a constant expression for IS_OBJECT that's an enum (ZEND_ASSERT)
That's consistent with the overall approach to forbidding magic methods such as ArrayAccess used elsewhere
It'd be useful to add the success/failure tests to the implementation
/* Objects or references cannot occur in a constant expression. */ is out of date
<?php
enum Suit implements IteratorAggregate {
public function getIterator() {
echo "in getIterator\n";
return new ArrayObject([new stdClass()]);
}
case HEARTS;
}
// const EXAMPLE = [...Suit::HEARTS]; // E_COMPILE_ERROR
var_dump([...Suit::HEARTS]); // this doesn't crash.
static zend_result zend_ast_add_unpacked_element(zval *result, zval *expr) {
if (EXPECTED(Z_TYPE_P(expr) == IS_ARRAY)) {
HashTable *ht = Z_ARRVAL_P(expr);
zval *val;
zend_string *key;
ZEND_HASH_FOREACH_STR_KEY_VAL(ht, key, val) {
if (key) {
zend_throw_error(NULL, "Cannot unpack array with string keys");
return FAILURE;
} else {
if (!zend_hash_next_index_insert(Z_ARRVAL_P(result), val)) {
zend_throw_error(NULL,
"Cannot add element to the array as the next element is already occupied");
return FAILURE;
}
Z_TRY_ADDREF_P(val);
}
} ZEND_HASH_FOREACH_END();
return SUCCESS;
}
/* Objects or references cannot occur in a constant expression. */
zend_throw_error(NULL, "Only arrays and Traversables can be unpacked");
return FAILURE;
}
I forgot about this php feature earlier -
...
unpacks an traversable, making it implicitly call traversable helpers.For enums, this should still be a CompileError, but would be more useful to make the error message
Cannot unpack enums in a constant expression
for IS_OBJECT that's an enum (ZEND_ASSERT)It'd be useful to add the success/failure tests to the implementation
/* Objects or references cannot occur in a constant expression. */
is out of date