Skip to content

Conversation

@staabm
Copy link
Contributor

@staabm staabm commented Nov 13, 2022

Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Two problems here:

  1. chdir($dir) ? 'foo' : 'bar' - in the else branch $dir will be considered ''
  2. If you pass non-empty-string to chdir(...), you'll get "always true" error.

Both can be solved with =non-empty-string. See: phpstan/phpstan#8348 + phpstan/phpstan#8351

@clxmstaab clxmstaab force-pushed the file-fn branch 2 times, most recently from 49564b7 to 766c8d9 Compare November 14, 2022 14:12
Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To make sure that = actually fixes these problems, you should have tested the else condition types and also put a test about this in ImpossibleCheckTypeFunctionCallRule (before adding the = everywhere). Please verify this was originally a problem and that it's fixed after the change. I'm sure you can find the previous version in your reflog :) It's e117fce or 49564b7.

@staabm
Copy link
Contributor Author

staabm commented Nov 20, 2022

good point.

2) PHPStan\Rules\Comparison\ImpossibleCheckTypeFunctionCallRuleTest::testBug6788
Failed asserting that two strings are identical.
--- Expected
+++ Actual
@@ @@
-'
+'13: Call to function chdir() with non-empty-string will always evaluate to true.
+    💡 Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.
+15: Call to function chdir() with non-falsy-string will always evaluate to true.
+    💡 Because the type is coming from a PHPDoc, you can turn off this check by setting <fg=cyan>treatPhpDocTypesAsCertain: false</> in your <fg=cyan>%configurationFile%</>.
 '

@staabm staabm changed the base branch from 1.9.x to 1.11.x June 12, 2024 12:02
@staabm
Copy link
Contributor Author

staabm commented Jun 12, 2024

the last commit is fixing cases like

<?php

namespace Bug4816;

use function PHPStan\Testing\assertType;

function (string $x): void {
	if (is_dir($x)) {
		assertType('true', is_dir($x));
	}
};

(so we don't regress 1eaef04)


my understanding is, that because this PR adds stubs with @phpstan-assert the specifier does no longer invoke handleDefaultTruthyOrFalseyContext in

$assertions = $functionReflection->getAsserts();
if ($assertions->getAll() !== []) {
$parametersAcceptor ??= ParametersAcceptorSelector::selectFromArgs($scope, $expr->getArgs(), $functionReflection->getVariants(), $functionReflection->getNamedArgumentsVariants());
$asserts = $assertions->mapTypes(static fn (Type $type) => TemplateTypeHelper::resolveTemplateTypes(
$type,
$parametersAcceptor->getResolvedTemplateTypeMap(),
$parametersAcceptor instanceof ParametersAcceptorWithPhpDocs ? $parametersAcceptor->getCallSiteVarianceMap() : TemplateTypeVarianceMap::createEmpty(),
TemplateTypeVariance::createInvariant(),
));
$specifiedTypes = $this->specifyTypesFromAsserts($context, $expr, $asserts, $parametersAcceptor, $scope);
if ($specifiedTypes !== null) {
return $specifiedTypes;
}
}
}
return $this->handleDefaultTruthyOrFalseyContext($context, $rootExpr, $expr, $scope);

and that the reason why my previous code sample did regress. After adding handleDefaultTruthyOrFalseyContext I can see other things regress though :).

@rvanvelzen could you give me a hand? why do we not invoke handleDefaultTruthyOrFalseyContext when taking the path thru specifyTypesFromAsserts. is this expected or an oversight?

btw: I noticed we also don't invoke handleDefaultTruthyOrFalseyContext when we take the path thru specifyTypesFromConditionalReturnType.

@thg2k
Copy link
Contributor

thg2k commented Jun 12, 2024

I had no idea that the assertion would actually assert the opposite if the condition is not met. This is very counter-intuitive for me.. I think the behavior with "=" should be the default and there should rather be another modifier to request the double behavior.

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Improve support for is_file and family

3 participants