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

ltrim(class-string, '\\') should return a class-string #8218

Closed
Tofandel opened this issue Jul 6, 2022 · 3 comments · Fixed by #8219
Closed

ltrim(class-string, '\\') should return a class-string #8218

Tofandel opened this issue Jul 6, 2022 · 3 comments · Fixed by #8219

Comments

@Tofandel
Copy link
Contributor

Tofandel commented Jul 6, 2022

When using

    /**
     * Removes the prepended backslash of a class string to conform with how php outputs class names
     *
     * @psalm-param class-string $className
     *
     * @psalm-return class-string
     */
    function normalizeClassName(string $className): string
    {
        return ltrim($className, '\\');
    }

2 errors will be thrown

ERROR: MoreSpecificReturnType - The declared return type 'class-string' for normalizeClassName is more specific than the inferred return type 'string' (see https://psalm.dev/070)
     * @psalm-return class-string

ERROR: LessSpecificReturnStatement - The type 'string' is more general than the declared return type 'class-string' for normalizeClassName (see https://psalm.dev/129)
        return ltrim($className, '\\');

It would be a nice addition to avoid this false negatives as this specific ltrim of a class string will always result in the same class-string being returned

Psalm should detect this very specific ltrim call if the input is a class-string and in that case infer a class-string type instead of a string

This issue also exists for phpstan phpstan/phpstan#7483

@Tofandel
Copy link
Contributor Author

Tofandel commented Jul 6, 2022

@psalm-github-bot
Copy link

I found these snippets:

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

/**
  * Removes the prepended backslash of a class string to conform with how php outputs class names
  *
  * @psalm-param class-string $className
  *
  * @psalm-return class-string
  */
function normalizeClassName(string $className): string
{
    return ltrim($className, '\\');
}
Psalm output (using commit fbd240b):

INFO: LessSpecificReturnStatement - 12:12 - The type 'string' is more general than the declared return type 'class-string' for normalizeClassName

INFO: MoreSpecificReturnType - 8:19 - The declared return type 'class-string' for normalizeClassName is more specific than the inferred return type 'string'

@Tofandel
Copy link
Contributor Author

Tofandel commented Jul 6, 2022

I have very little knowledge of the inner working of psalm, but would 4.x...Tofandel:psalm:patch-1
do the trick?

Or is something like this possible:
@return ($string is class-string ? ( $characters is '\\' ? class-string : string ) : string )

Edit:
Gave it a try, works flawlessly

Tofandel added a commit to Tofandel/psalm that referenced this issue Jul 6, 2022
orklah added a commit that referenced this issue Jul 6, 2022
fix: ltrim may return class-string #8218
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 a pull request may close this issue.

1 participant