enum-comparison icon indicating copy to clipboard operation
enum-comparison copied to clipboard

Improve issue message for array unpacking of Traversable enum

Open TysonAndre opened this issue 4 years ago • 0 comments

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;
}

TysonAndre avatar Feb 04 '21 00:02 TysonAndre