Now that operator errors are detected more accurately, we no longer
have any cases where we throw a compile-time error instead of a
run-time exception, so we can drop this check now.
For division (rather than modulus) we should check the double
value, otherwise the result might be zero after integer truncation,
but not zero as a floating point value.
This may produce different behavior if operator overloading is
involved, and may change the error message.
If there's strong interest, this could be done in the DFA pass
with available type information. It does not look particularly
practically useful to me though.
This reduces the number of places where the error message template is used.
Also promote the mb_check_encoding() warning to ValueError and add a test to cover the behaviour.
Instead of looping, use straight-line code with the following
layout:
1. Try to apply the base operation on the dereferenced operands.
2. Try overloaded object operations.
3. Try to convert operands to number, else error out.
4. Apply the base operation on the converted operands.
This makes the code easier to reason about and fixes some edge-case
bugs:
1. We should only try invoking operator overloading once prior to
type conversion. Previously it was invoked both before and after
type conversion.
2. We should not modify any values if an exception is thrown.
Previously we sometimes modified the LHS of a compound assignment
operator.
3. If conversion of the first operand fails, we no longer try to
convert the second operand. I think the previous behavior here
was fine as well, but this still seems a more typical.
This will also make some followup changes I have in mind simpler.
Promotes only the warnings where the encoding comes only from a string.
Functions which accept an array of encodings will be fixed at a later stage.
Closes GH-5317
Avoid subtle differences in behavior depending on whether the
handler is absent or returns FAILURE.
If you previously set cast_object to NULL, create a handler that
always returns FAILURE instead.
To explicitly indicate that objects are uncomparable. For now
this has no functional difference from the usual 1 return value,
but makes intent clearer.
Make cast_object return FAILURE for casts to int/float, rather than
throwing a notice and returning SUCCESS. Instead move the emission
of the notice to the code invoking cast_object. This will allow us
to customize the behavior per call-site.
This change is written to be NFC, and the code in
zend_std_compare_objects() should illustrate the current behavior
doesn't make a lot of sense.
Even if default_charset is set to "", we should still return
"UTF-8" as the default value here. Setting default_charset to ""
suppresses the header emission, but shouldn't change anything
about our encoding defaults.