diff --git a/compiler/class-assumptions.cpp b/compiler/class-assumptions.cpp index 1ea3928f4a..855887eb37 100644 --- a/compiler/class-assumptions.cpp +++ b/compiler/class-assumptions.cpp @@ -155,12 +155,15 @@ ClassPtr Assumption::extract_instance_from_type_hint(const TypeHint *a) { // between them, so we can call a more expensive get_common_base_or_interface() method here; // the method below is somewhat conservative, but it's good enough in the usual cases ClassPtr result; - ClassPtr first = as_pipe->items[0]->try_as()->resolve(); - for (int i = 1; i < as_pipe->items.size(); ++i) { - if (as_pipe->items[i]->try_as()) { + ClassPtr first; + for (const auto *item : as_pipe->items) { + if (item->try_as()) { continue; // we know that it's tp_Null } - ClassPtr other = extract_instance_from_type_hint(as_pipe->items[i]); + if (!first) { + first = item->try_as()->resolve(); + } + ClassPtr other = extract_instance_from_type_hint(item); const auto common_bases = first->get_common_base_or_interface(other); if (common_bases.size() != 1) { return ClassPtr{}; diff --git a/tests/phpt/typehints/return_types/16_null_first_in_pipe.php b/tests/phpt/typehints/return_types/16_null_first_in_pipe.php new file mode 100644 index 0000000000..886b55648e --- /dev/null +++ b/tests/phpt/typehints/return_types/16_null_first_in_pipe.php @@ -0,0 +1,32 @@ +@ok +call(); + execute2()->call(); + var_dump(execute3()); +} + +main();