Crell / enum-comparison

A comparison of enumerations and similar features in different languages
82 stars 7 forks source link

Improve issue message for array unpacking of Traversable enum #71

Closed TysonAndre closed 2 years ago

TysonAndre commented 3 years ago

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

<?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 commented 2 years ago

I forgot about this and saw it while going through old issues. I'll file an issue in php-src