Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Next Next commit
Define Stringable with __toString():string method
  • Loading branch information
nicolas-grekas committed Mar 2, 2020
commit 9e775db02567d3b90694ebb43f0225875a48e8c9
2 changes: 1 addition & 1 deletion Zend/tests/bug26166.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,6 @@ try {
--EXPECT--
Hello World!
===NONE===
Method NoneTest::__toString() must return a string value
Return value of NoneTest::__toString() must be of type string, none returned
===THROW===
This is an error!
2 changes: 1 addition & 1 deletion Zend/tests/list_keyed_evaluation_order.inc
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

// Observer objects for the Zend/tests/list_keyed_evaluation_order.* tests

class Stringable
class StringCapable
{
private $name;
public function __construct(string $name) {
Expand Down
4 changes: 2 additions & 2 deletions Zend/tests/list_keyed_evaluation_order.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ list() with keys, evaluation order

require_once "list_keyed_evaluation_order.inc";

$a = new Stringable("A");
$c = new Stringable("C");
$a = new StringCapable("A");
$c = new StringCapable("C");

$e = new IndexableRetrievable("E", new Indexable(["A" => "value for offset A", "C" => "value for offset C"]));

Expand Down
10 changes: 5 additions & 5 deletions Zend/tests/list_keyed_evaluation_order_nested.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,11 @@ list() with keys, evaluation order: nested

require_once "list_keyed_evaluation_order.inc";

$a = new Stringable("A");
$c = new Stringable("C");
$f = new Stringable("F");
$g = new Stringable("G");
$i = new Stringable("I");
$a = new StringCapable("A");
$c = new StringCapable("C");
$f = new StringCapable("F");
$g = new StringCapable("G");
$i = new StringCapable("I");

$k = new IndexableRetrievable("K", new Indexable([
"A" => "offset value for A",
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable implements Stringable {
public function __toString() {
return "foobar";
}
Expand All @@ -40,7 +40,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -106,7 +106,7 @@ int(0)
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -160,7 +160,7 @@ float(0)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -213,7 +213,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
string(6) "foobar"

Expand Down Expand Up @@ -266,7 +266,7 @@ bool(false)
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#%s (0) {
*** Trying object(StringCapable)#%s (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_return_basic.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $functions = [
'bool' => function ($b): bool { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -42,7 +42,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -94,7 +94,7 @@ int(0)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type int, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type int, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -132,7 +132,7 @@ float(0)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type float, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type float, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -169,7 +169,7 @@ string(0) ""
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type string, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
string(6) "foobar"
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -206,7 +206,7 @@ bool(false)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type bool, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type bool, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_return_basic_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ $functions = [
'bool' => function ($b): bool { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -42,7 +42,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -94,7 +94,7 @@ int(0)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type int, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type int, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -132,7 +132,7 @@ float(0)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type float, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type float, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -169,7 +169,7 @@ string(0) ""
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type string, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
string(6) "foobar"
*** Trying resource(5) of type (stream)
Expand Down Expand Up @@ -206,7 +206,7 @@ bool(false)
*** Trying object(stdClass)#6 (0) {
}
*** Caught Return value of {closure}() must be of type bool, object returned in %s on line %d
*** Trying object(Stringable)#7 (0) {
*** Trying object(StringCapable)#7 (0) {
}
*** Caught Return value of {closure}() must be of type bool, object returned in %s on line %d
*** Trying resource(5) of type (stream)
Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_strict.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -34,7 +34,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -100,7 +100,7 @@ int(2147483647)
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -153,7 +153,7 @@ float(NAN)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -206,7 +206,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

Expand Down Expand Up @@ -259,7 +259,7 @@ bool(false)
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
12 changes: 6 additions & 6 deletions Zend/tests/type_declarations/scalar_strict_64bit.phpt
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ $functions = [
'bool' => function (bool $b) { return $b; }
];

class Stringable {
class StringCapable {
public function __toString() {
return "foobar";
}
Expand All @@ -34,7 +34,7 @@ $values = [
NULL,
[],
new StdClass,
new Stringable,
new StringCapable,
fopen("data:text/plain,foobar", "r")
];

Expand Down Expand Up @@ -100,7 +100,7 @@ int(9223372036854775807)
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($i) must be of type int, object given, called in %s on line %d

Expand Down Expand Up @@ -153,7 +153,7 @@ float(NAN)
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($f) must be of type float, object given, called in %s on line %d

Expand Down Expand Up @@ -206,7 +206,7 @@ string(0) ""
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($s) must be of type string, object given, called in %s on line %d

Expand Down Expand Up @@ -259,7 +259,7 @@ bool(false)
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

*** Trying object(Stringable)#6 (0) {
*** Trying object(StringCapable)#6 (0) {
}
*** Caught {closure}(): Argument #1 ($b) must be of type bool, object given, called in %s on line %d

Expand Down
19 changes: 12 additions & 7 deletions Zend/zend_compile.c
Original file line number Diff line number Diff line change
Expand Up @@ -5714,22 +5714,26 @@ static zend_bool zend_is_valid_default_value(zend_type type, zval *value)
return 0;
}

void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast) /* {{{ */
void zend_compile_params(zend_ast *ast, zend_ast *return_type_ast, uint32_t fallback_return_type) /* {{{ */
{
zend_ast_list *list = zend_ast_get_list(ast);
uint32_t i;
zend_op_array *op_array = CG(active_op_array);
zend_arg_info *arg_infos;
zend_string *optional_param = NULL;

if (return_type_ast) {
if (return_type_ast || fallback_return_type) {
/* Use op_array->arg_info[-1] for return type */
arg_infos = safe_emalloc(sizeof(zend_arg_info), list->children + 1, 0);
arg_infos->name = NULL;
arg_infos->type = zend_compile_typename(
return_type_ast, /* force_allow_null */ 0, /* use_arena */ 0);
ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
if (return_type_ast) {
arg_infos->type = zend_compile_typename(
return_type_ast, /* force_allow_null */ 0, /* use_arena */ 0);
ZEND_TYPE_FULL_MASK(arg_infos->type) |= _ZEND_ARG_INFO_FLAGS(
(op_array->fn_flags & ZEND_ACC_RETURN_REFERENCE) != 0, /* is_variadic */ 0);
} else {
arg_infos->type = (zend_type) ZEND_TYPE_INIT_CODE(fallback_return_type, 0, 0);
}
arg_infos++;
op_array->fn_flags |= ZEND_ACC_HAS_RETURN_TYPE;
} else {
Expand Down Expand Up @@ -6294,7 +6298,8 @@ void zend_compile_func_decl(znode *result, zend_ast *ast, zend_bool toplevel) /*
zend_stack_push(&CG(loop_var_stack), (void *) &dummy_var);
}

zend_compile_params(params_ast, return_type_ast);
zend_compile_params(params_ast, return_type_ast,
is_method && zend_string_equals_literal_ci(decl->name, "__toString") ? IS_STRING : 0);
if (CG(active_op_array)->fn_flags & ZEND_ACC_GENERATOR) {
zend_mark_function_as_generator();
zend_emit_op(NULL, ZEND_GENERATOR_CREATE, NULL, NULL);
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -763,7 +763,6 @@ static const zend_function_entry zend_funcs_throwable[] = {
ZEND_ABSTRACT_ME(throwable, getTrace, arginfo_class_Throwable_getTrace)
ZEND_ABSTRACT_ME(throwable, getPrevious, arginfo_class_Throwable_getPrevious)
ZEND_ABSTRACT_ME(throwable, getTraceAsString, arginfo_class_Throwable_getTraceAsString)
ZEND_ABSTRACT_ME(throwable, __toString, arginfo_class_Throwable___toString)
ZEND_FE_END
};
/* }}} */
Expand Down Expand Up @@ -805,6 +804,7 @@ void zend_register_default_exception(void) /* {{{ */
zend_class_entry ce;

REGISTER_MAGIC_INTERFACE(throwable, Throwable);
zend_class_implements(zend_ce_throwable, 1, zend_ce_stringable);

memcpy(&default_exception_handlers, &std_object_handlers, sizeof(zend_object_handlers));
default_exception_handlers.clone_obj = NULL;
Expand Down
Loading