Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Incorrectly asserting non-empty-list after combining with empty list #9787

Conversation

robchett
Copy link
Contributor

@robchett robchett commented May 14, 2023

Fixes #9594

@robchett robchett changed the title Fix for Fix for #9594 - incorrectly asserting non-empty-list after combining with empty list May 14, 2023
@robchett robchett force-pushed the remove_non-empty-list_status_when_combining_with_empty branch from 7b0cdb3 to 762670f Compare May 14, 2023 11:49
@robchett
Copy link
Contributor Author

Tracked this down to here:

if (!$combination->array_type_params || $combination->array_type_params[1]->isNever()) {
if (!$overwrite_empty_array
&& $combination->array_type_params
) {
foreach ($combination->objectlike_entries as &$objectlike_entry) {
$objectlike_entry = $objectlike_entry->setPossiblyUndefined(true);
}
unset($objectlike_entry);
}
if ($combination->objectlike_value_type
&& $combination->objectlike_value_type->isMixed()
&& $combination->array_type_params
&& !$combination->array_type_params[1]->isNever()
) {
$combination->objectlike_entries = array_filter(
$combination->objectlike_entries,
static fn(Union $type): bool => !$type->possibly_undefined,
);
}
if ($combination->objectlike_entries) {
$fallback_key_type = null;
if ($combination->objectlike_key_type) {
$fallback_key_type = $combination->objectlike_key_type;
} elseif ($combination->array_type_params
&& $combination->array_type_params[0]->isArrayKey()
) {
$fallback_key_type = $combination->array_type_params[0];
}
$fallback_value_type = null;
if ($combination->objectlike_value_type) {
$fallback_value_type = $combination->objectlike_value_type;
} elseif ($combination->array_type_params
&& $combination->array_type_params[1]->isMixed()
) {
$fallback_value_type = $combination->array_type_params[1];
}
$sealed = $combination->objectlike_sealed && (
!$combination->array_type_params
|| (isset($combination->array_type_params[1])
&& $combination->array_type_params[1]->isNever()
)
);
if ($combination->all_arrays_callable) {
$objectlike = new TCallableKeyedArray(
$combination->objectlike_entries,
null,
$sealed || $fallback_key_type === null || $fallback_value_type === null
? null
: [$fallback_key_type, $fallback_value_type],
(bool)$combination->all_arrays_lists,
$from_docblock,
);
} else {
$objectlike = new TKeyedArray(
$combination->objectlike_entries,
null,
$sealed || $fallback_key_type === null || $fallback_value_type === null
? null
: [$fallback_key_type, $fallback_value_type],
(bool)$combination->all_arrays_lists,
$from_docblock,
);
}
$new_types[] = $objectlike;
} else {
$key_type = $combination->objectlike_key_type ?? Type::getArrayKey();
$value_type = $combination->objectlike_value_type ?? Type::getMixed();
if ($combination->array_always_filled) {
$array_type = new TNonEmptyArray([$key_type, $value_type]);
} else {
$array_type = new TArray([$key_type, $value_type]);
}
$new_types[] = $array_type->setFromDocblock($from_docblock);
}
// if we're merging an empty array with an object-like, clobber empty array
$combination->array_type_params = [];
}

Need to get my head around the interactions between $overwrite_empty_array, $objectlike_entry->setPossiblyUndefined and $combination->array_type_params = [];

Current best effort is switching $overwrite_empty_array at the callsite

if (!$new_child_type) {
if ($templated_assignment) {
$new_child_type = $root_type;
} else {
$new_child_type = Type::combineUnionTypes(
$root_type,
$array_assignment_type,
$codebase,
true,
true,
);
}
}

but it needs to be smarter than that as then we loose [] + T' = non-empty-list<T>

@orklah
Copy link
Collaborator

orklah commented May 20, 2023

Yeah, this breaks things pretty dramatically :D

Not sure if I'll be able to find time to dig into it to help in the foreseeable future

@robchett robchett force-pushed the remove_non-empty-list_status_when_combining_with_empty branch from 762670f to 8ea2e75 Compare October 9, 2023 18:19
@robchett robchett changed the title Fix for #9594 - incorrectly asserting non-empty-list after combining with empty list Incorrectly asserting non-empty-list after combining with empty list Oct 9, 2023
@robchett robchett force-pushed the remove_non-empty-list_status_when_combining_with_empty branch 3 times, most recently from 8d4bdd6 to 6044cc7 Compare October 26, 2023 16:31
@robchett
Copy link
Contributor Author

Finally found the time to crack this, nested array type combiners were inheriting overwrite_empty_array so I've made it only apply to root level array type modifications and not any value types.

@orklah orklah added the release:fix The PR will be included in 'Fixes' section of the release notes label Nov 3, 2023
@orklah
Copy link
Collaborator

orklah commented Nov 3, 2023

Thanks!

@orklah orklah merged commit b9c82d3 into vimeo:master Nov 3, 2023
38 of 40 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
release:fix The PR will be included in 'Fixes' section of the release notes
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants