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

result of count() not taken into account #4700

Closed
pauljherring opened this issue Mar 13, 2021 · 5 comments
Closed

result of count() not taken into account #4700

pauljherring opened this issue Mar 13, 2021 · 5 comments
Labels
Milestone

Comments

@pauljherring
Copy link

Bug report

.. or at least I think that may be what's wrong here...

If count($a) on an array assigned using multiple $a[] = ... returns more than zero items, then$a[0] should exist.

Code snippet that reproduces the problem

https://phpstan.org/r/bfc2aa88-7001-4b48-8b96-1ed4e72600e7

<?php declare(strict_types = 1);
/** 
 * Abbreviate an address - always show the first line, then work backwards from the most generic at the end
 * @param array{a?: string,
 * b?: string,
 * c?: string,
 * d?: string,
 * e?: string,
 * } $array array of things to show
 * @param int $count how many of them to show, the first one and $count-1
 * @return string;
 */
function abbrev($array, $count){
	if ($count < 1){
		return '';
	}
	$a = [];
	if (isset($array['a'])) $a[] = $array['a'];
	if (isset($array['b'])) $a[] = $array['b'];
	if (isset($array['c'])) $a[] = $array['c'];
	if (isset($array['d'])) $a[] = $array['d'];
	if (isset($array['e'])) $a[] = $array['e'];
	if (count($a) >= $count){ // count is > 0, so $a[0] must exist...
		$ret = implode(', ', array_merge([$a[0]], array_slice($a, -($count-1))));  // line 24
	}else{
		$ret = implode(', ', $a);
	}
	return $ret;
}

$address = [
	'a' => 'a',
	'b' => 'b',
	// c omitted
	'd' => 'd',
	'e' => 'e',
];

echo abbrev($address, 2)."\n";
echo abbrev($address, 5)."\n";
echo abbrev($address, 7)."\n";

$address = [
];
echo abbrev($address, 2)."\n";
echo abbrev($address, 5)."\n";
echo abbrev($address, 7)."\n";

Actual output

24 | Offset 0 does not exist on array()\|array(0 => string, ?1 => string, ?2 => string, ?3 => string, ?4 => string).

Expected output

No errors!
@ondrejmirtes
Copy link
Member

This works: https://phpstan.org/r/846385ab-8a48-4fab-92b1-2fbc3d661c10

So it's just that TypeSpecifier does not support count($a) >= positive-int...

@ondrejmirtes ondrejmirtes added this to the Easy fixes milestone Mar 13, 2021
@pauljherring
Copy link
Author

This works: https://phpstan.org/r/846385ab-8a48-4fab-92b1-2fbc3d661c10

But changes how the function works, sadly.

Ta, anyway.

@pauljherring
Copy link
Author

But changes how the function works, sadly.

Found some cruft to add to fix that..

https://phpstan.org/r/d83efb70-2a4a-40c9-94c6-dcc34d8e7d3f

.. and I do appreciate your efforts on this btw - it's helped me a lot.

@ondrejmirtes
Copy link
Member

Fixed: phpstan/phpstan-src@7b417c7

@github-actions
Copy link

github-actions bot commented May 4, 2021

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

@github-actions github-actions bot locked as resolved and limited conversation to collaborators May 4, 2021
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
Projects
None yet
Development

No branches or pull requests

2 participants