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

opcache.jit=1205 causes an assertion #9350

Closed
edsrzf opened this issue Feb 20, 2023 · 7 comments
Closed

opcache.jit=1205 causes an assertion #9350

edsrzf opened this issue Feb 20, 2023 · 7 comments

Comments

@edsrzf
Copy link
Contributor

edsrzf commented Feb 20, 2023

After updating from 5.6.0 to 5.7.1, I'm seeing an assertion when type-checking my code. It happens often, but not 100% of the time.

If I change opcache.jit from 1205 to 1254 (which is the default), the assertion goes away.

System Information

OS: MacOS 13.2.1
CPU: arm64
PHP: 8.1.15

Stack Trace

Uncaught AssertionError: assert(false) in vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php:189
#0 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOp/ConcatAnalyzer.php(181): assert(false, 'assert(count($r...')
#1 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/BinaryOpAnalyzer.php(139): Psalm\Internal\Analyzer\Statements\Expression\BinaryOp\ConcatAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Scalar\MagicConst\Dir), Object(PhpParser\Node\Scalar\String_), Object(Psalm\Context), Object(Psalm\Type\Union))
#2 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(266): Psalm\Internal\Analyzer\Statements\Expression\BinaryOpAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\BinaryOp\Concat), Object(Psalm\Context), 0, false)
#3 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\BinaryOp\Concat), Object(Psalm\Context), false, NULL, false, NULL, false)
#4 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/ArgumentsAnalyzer.php(241): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\BinaryOp\Concat), Object(Psalm\Context), false, NULL, false, NULL)
#5 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/FunctionCallAnalyzer.php(186): Psalm\Internal\Analyzer\Statements\Expression\Call\ArgumentsAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Array, Array, 'realpath', true, Object(Psalm\Context), Object(Psalm\Internal\Type\TemplateResult))
#6 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(296): Psalm\Internal\Analyzer\Statements\Expression\Call\FunctionCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\FuncCall), Object(Psalm\Context), Object(Psalm\Internal\Type\TemplateResult))
#7 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\FuncCall), Object(Psalm\Context), false, NULL, false, NULL, false)
#8 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/AssignmentAnalyzer.php(242): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\FuncCall), Object(Psalm\Context))
#9 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(544): Psalm\Internal\Analyzer\Statements\Expression\AssignmentAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\PropertyFetch), Object(PhpParser\Node\Expr\FuncCall), NULL, Object(Psalm\Context), NULL, Array, NULL)
#10 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(178): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyzeAssignment(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Assign), Object(Psalm\Context), true)
#11 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Assign), Object(Psalm\Context), false, NULL, true, NULL, false)
#12 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(566): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\Assign), Object(Psalm\Context), false, NULL, true)
#13 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(195): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\Expression), Object(Psalm\Context), NULL)
#14 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(468): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context), NULL, true)
#15 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php(131): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), NULL, true)
#16 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(414): Psalm\Internal\Analyzer\ClassLikeAnalyzer->getMethodMutations('__construct', Object(Psalm\Context))
#17 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1393): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), true)
#18 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(381): Psalm\Internal\Analyzer\ProjectAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), '...', 'apps/backend/co...')
#19 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php(130): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context))
#20 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(882): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\ExistingAtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(PhpParser\Node\Identifier), Array, Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Object(Psalm\Internal\MethodIdentifier), 'ProjectConfigur...', Object(Psalm\Storage\ClassLikeStorage), false, NULL)
#21 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(207): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::handleNamedCall(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(PhpParser\Node\Identifier), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Array, 'ProjectConfigur...', false, true, NULL)
#22 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php(208): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), false, false, false, true, NULL)
#23 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(190): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), NULL)
#24 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), false, NULL, true, NULL, false)
#25 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(566): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), false, NULL, true)
#26 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(195): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\Expression), Object(Psalm\Context), NULL)
#27 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(468): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context), NULL, true)
#28 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php(131): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), NULL, true)
#29 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(414): Psalm\Internal\Analyzer\ClassLikeAnalyzer->getMethodMutations('__construct', Object(Psalm\Context))
#30 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1393): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), true)
#31 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(381): Psalm\Internal\Analyzer\ProjectAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), '...', 'apps/backend/co...')
#32 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php(130): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context))
#33 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(882): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\ExistingAtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(PhpParser\Node\Identifier), Array, Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Object(Psalm\Internal\MethodIdentifier), 'sfApplicationCo...', Object(Psalm\Storage\ClassLikeStorage), false, NULL)
#34 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(207): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::handleNamedCall(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(PhpParser\Node\Identifier), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Array, 'sfApplicationCo...', false, true, NULL)
#35 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php(208): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), false, false, false, true, NULL)
#36 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(190): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), NULL)
#37 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), false, NULL, true, NULL, false)
#38 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(566): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Expr\StaticCall), Object(Psalm\Context), false, NULL, true)
#39 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(195): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(PhpParser\Node\Stmt\Expression), Object(Psalm\Context), NULL)
#40 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(468): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context), NULL, true)
#41 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassLikeAnalyzer.php(131): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), NULL, true)
#42 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(414): Psalm\Internal\Analyzer\ClassLikeAnalyzer->getMethodMutations('__construct', Object(Psalm\Context))
#43 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1393): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), true)
#44 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(381): Psalm\Internal\Analyzer\ProjectAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context), '...', 'apps/backend/co...')
#45 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/ExistingAtomicStaticCallAnalyzer.php(130): Psalm\Internal\Analyzer\FileAnalyzer->getMethodMutations(Object(Psalm\Internal\MethodIdentifier), Object(Psalm\Context))
#46 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(882): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\ExistingAtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Node\VirtualIdentifier), Array, Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Object(Psalm\Internal\MethodIdentifier), 'VendApplication...', Object(Psalm\Storage\ClassLikeStorage), false, NULL)
#47 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticMethod/AtomicStaticCallAnalyzer.php(207): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::handleNamedCall(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Node\VirtualIdentifier), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), Array, 'VendApplication...', false, true, NULL)
#48 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/Expression/Call/StaticCallAnalyzer.php(208): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticMethod\AtomicStaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Context), Object(Psalm\Type\Atomic\TNamedObject), false, false, false, true, NULL)
#49 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(190): Psalm\Internal\Analyzer\Statements\Expression\Call\StaticCallAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Context), NULL)
#50 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/Statements/ExpressionAnalyzer.php(86): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::handleExpression(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Context), false, Object(Psalm\Context), true, NULL, false)
#51 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(566): Psalm\Internal\Analyzer\Statements\ExpressionAnalyzer::analyze(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Expr\VirtualStaticCall), Object(Psalm\Context), false, Object(Psalm\Context), true)
#52 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/StatementsAnalyzer.php(195): Psalm\Internal\Analyzer\StatementsAnalyzer::analyzeStatement(Object(Psalm\Internal\Analyzer\StatementsAnalyzer), Object(Psalm\Node\Stmt\VirtualExpression), Object(Psalm\Context), Object(Psalm\Context))
#53 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FunctionLikeAnalyzer.php(468): Psalm\Internal\Analyzer\StatementsAnalyzer->analyze(Array, Object(Psalm\Context), Object(Psalm\Context), true)
#54 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1799): Psalm\Internal\Analyzer\FunctionLikeAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Internal\Provider\NodeDataProvider), Object(Psalm\Context))
#55 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(1226): Psalm\Internal\Analyzer\ClassAnalyzer->analyzeClassMethod(Object(Psalm\Node\Stmt\VirtualClassMethod), Object(Psalm\Storage\ClassLikeStorage), Object(Psalm\Internal\Analyzer\ClassAnalyzer), Object(Psalm\Context), Object(Psalm\Context), true)
#56 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ClassAnalyzer.php(551): Psalm\Internal\Analyzer\ClassAnalyzer->checkPropertyInitialization(Object(Psalm\Codebase), Object(Psalm\Config), Object(Psalm\Storage\ClassLikeStorage), Object(Psalm\Context), Object(Psalm\Context), NULL)
#57 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/FileAnalyzer.php(203): Psalm\Internal\Analyzer\ClassAnalyzer->analyze(Object(Psalm\Context), Object(Psalm\Context))
#58 vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(1581): Psalm\Internal\Analyzer\FileAnalyzer->analyze()
#59 vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(522): Psalm\Internal\Codebase\Analyzer->analysisWorker(0, '...')
#60 vendor/vimeo/psalm/src/Psalm/Internal/Codebase/Analyzer.php(272): Psalm\Internal\Codebase\Analyzer->doAnalysis(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1)
#61 vendor/vimeo/psalm/src/Psalm/Internal/Analyzer/ProjectAnalyzer.php(1187): Psalm\Internal\Codebase\Analyzer->analyzeFiles(Object(Psalm\Internal\Analyzer\ProjectAnalyzer), 1, false, false)
#62 vendor/vimeo/psalm/src/Psalm/Internal/Cli/Psalm.php(374): Psalm\Internal\Analyzer\ProjectAnalyzer->checkPaths(Array)
#63 vendor/vimeo/psalm/psalm(9): Psalm\Internal\Cli\Psalm::run(Array)
#64 vendor/bin/psalm(120): include('...')
#65 {main}

Code

The code that triggers this assertion is:

<?php

$v = __DIR__ . '';
// Also works:
// $v = __FILE__ . '';

(This can't be reproduced with a snippet because the snippet likely runs on a different platform.)

Further Debugging

This is probably a JIT bug in PHP. If I add some debug logging I see some truly unexplainable behavior:

Original code:

                    if ($literal_concat) {
                        assert(count($result_type_parts) === $combinations);
                        assert(count($result_type_parts) !== 0); // #8163
                        $result_type = new Union($result_type_parts);
                    }

With added debugging:

                    if ($literal_concat) {
                        if (count($result_type_parts) !== $combinations) {
                            var_dump(count($result_type_parts) === $combinations);
                            var_dump(count($result_type_parts));
                            var_dump($combinations);
                            assert(false);
                        }
                        assert(count($result_type_parts) === $combinations);
                        assert(count($result_type_parts) !== 0); // #8163
                        $result_type = new Union($result_type_parts);
                    }

When the assertion triggers, the output of this code is:

bool(false)
int(1)
int(1)

So, it's saying 1 !== 1, which is...puzzling, to say the least. Also, if I change the order of the logging and move var_dump($combinations) first, the output becomes:

int(1)
bool(true)
int(1)
@psalm-github-bot
Copy link

Hey @edsrzf, can you reproduce the issue on https://psalm.dev ?

@simitter
Copy link

Can confirm this problem m1 pro.
On older intel macs the problem does not seem to appear.

@danog
Copy link
Collaborator

danog commented Feb 20, 2023

Yep, this is an issue with the ARM64 JIT, can reproduce on my pi4 by scanning psalm itself

@danog
Copy link
Collaborator

danog commented Feb 20, 2023

I'm afraid switching to tracing JIT will not fix the issue, only postpone it until the JIT decides to compile that code segment when it gets hot enough.

The only workaround I see is running (function (int $_): void {})($combinations); before the assertions, or turning them into explicit ifs.

danog added a commit to zoonru/psalm that referenced this issue Feb 20, 2023
@edsrzf
Copy link
Contributor Author

edsrzf commented Feb 20, 2023

Anecdotally, I'm able to type-check a large code base using opcache.jit=1205. I don't know if there's a way to tell whether the code segment is getting hot enough to be JIT compiled.

@weirdan
Copy link
Collaborator

weirdan commented Feb 20, 2023

Is this reported to / fixed in https://github.com/php/php-src?

Yes it is: php/php-src#10635

@weirdan
Copy link
Collaborator

weirdan commented Feb 20, 2023

The fix is released in 5.7.2.

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

No branches or pull requests

4 participants