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

Literal string key is being casted to integer #8680

Closed
danog opened this issue Nov 7, 2022 · 6 comments · Fixed by #10481
Closed

Literal string key is being casted to integer #8680

danog opened this issue Nov 7, 2022 · 6 comments · Fixed by #10481
Labels

Comments

@danog
Copy link
Collaborator

danog commented Nov 7, 2022

https://psalm.dev/r/791f571f06

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/791f571f06
<?php

class a {
	private const REDIRECTS = [
		'a' => [
			'from' => '79268724911',
			'to' => '74950235931',
		],
		'b' => [
			'from' => '79313044964',
			'to' => '78124169167',
		],
	];
    
	private const SIP_FORMAT = 'sip:%s@voip.test.com:9090';
    
    /** @return array<string, string> */
    public function test(): array {
		$redirects = [];
		foreach (self::REDIRECTS as $redirect) {
			$redirects[$redirect['from']] = sprintf(self::SIP_FORMAT, $redirect['to']);
		}

		return $redirects;
    }
}
Psalm output (using commit 1986c8b):

ERROR: InvalidReturnStatement - 24:10 - The inferred type 'non-empty-array<'79268724911'|'79313044964'|79268724911|79313044964, string>' does not match the declared return type 'array<string, string>' for a::test

ERROR: InvalidReturnType - 17:17 - The declared return type 'array<string, string>' for a::test is incorrect, got 'non-empty-array<'79268724911'|'79313044964'|79268724911|79313044964, string>'

@danog danog added the bug label Nov 7, 2022
@orklah
Copy link
Collaborator

orklah commented Nov 7, 2022

Yeah, this is closely related to #4553

Basically, there's no way of guaranteeing a array<string, XXX>. In fact, your specific code doesn't return that. The keys are integers now: https://3v4l.org/rDcdn. However, if you try to access this array again using your string keys, that should still work

Unfortunately, this is the kind of issue where almost every move you'll make will break some use case. If I had to change something in PHP, this is one of the first thing I would change and I'm not the only one :p
https://twitter.com/OndrejMirtes/status/1577597275798478848
https://twitter.com/OndrejMirtes/status/1504736388247400449

@weirdan
Copy link
Collaborator

weirdan commented Nov 7, 2022

@orklah the literal array key type part looks wrong though: '79268724911'|'79313044964'|...

Shouldn't we remove those literal strings in this case?

@danog
Copy link
Collaborator Author

danog commented Nov 7, 2022

https://3v4l.org/rDcdn

Holy cow that's the weirdest thing I've ever seen, and I thought I knew all of PHP's weird quirks :P

Anyway I think this can be easily fixed by checking if the string is numeric, and in this case specifying only integers, as suggested by @weirdan.

@orklah
Copy link
Collaborator

orklah commented Nov 7, 2022

Shouldn't we remove those literal strings in this case?

I believe it was made on purpose to allow users to use the string again like this: https://psalm.dev/r/ecf0649a4d. This could possibly be removed but you'll have to handle the access side of things too and redo the implicit casting

But this will unfortunately work only with literals. For real life arrays with unknown string offset, you can never really be sure you won't end up with numeric-strings in there that will mess up your strictly typed array :p

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/ecf0649a4d
<?php

$a = '1111';

$b = [$a => 'b'];

$c = $b[$a];
/** @psalm-trace $c */;
Psalm output (using commit 1986c8b):

INFO: Trace - 8:23 - $c: 'b'

INFO: UnusedVariable - 5:1 - $b is never referenced or the value is not used

INFO: UnusedVariable - 7:1 - $c is never referenced or the value is not used

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants