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

Invalid suggestion for psalm --alter and strange const error #7973

Closed
ricardoboss opened this issue May 16, 2022 · 11 comments
Closed

Invalid suggestion for psalm --alter and strange const error #7973

ricardoboss opened this issue May 16, 2022 · 11 comments
Assignees
Labels

Comments

@ricardoboss
Copy link
Contributor

image

There's a lot to unpack here... Any idea why any of this is happening? I don't understand the error message (I have not declared any type for the const, it should infer the type from the value) and the --alter suggestion doesn't even work.

@psalm-github-bot
Copy link

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

@ricardoboss
Copy link
Contributor Author

Yeah, I can reproduce it... but why? https://psalm.dev/r/d757d80ca9

@psalm-github-bot
Copy link

I found these snippets:

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


interface Duration
{
	public const SECONDS_PER_MINUTE = 60;
	public const SECONDS_PER_HOUR = self::SECONDS_PER_MINUTE * self::MINUTES_PER_HOUR;
	public const SECONDS_PER_DAY = self::SECONDS_PER_HOUR * self::HOURS_PER_DAY;
    
    // THE LINE BELOW causes the error?
	public const SECONDS_PER_MONTH = self::SECONDS_PER_DAY * self::DAYS_PER_MONTH;
    
	public const MINUTES_PER_HOUR = 60;
	public const HOURS_PER_DAY = 24;
	public const DAYS_PER_MONTH = self::DAYS_PER_YEAR / self::MONTHS_PER_YEAR;
	public const DAYS_PER_YEAR = 365.2425; // average length of a Gregorian year over a complete leap cycle of 400 years
	public const MONTHS_PER_YEAR = 12;
}
Psalm output (using commit f960d71):

ERROR: InvalidConstantAssignmentValue - 15:15 - Duration::DAYS_PER_MONTH with declared type float(30.436875) cannot be assigned type float

@ricardoboss
Copy link
Contributor Author

Also, if I add:

/**
 * @psalm-suppress InvalidConstantAssignmentValue
 */

to the class, it still reports the errors. Is this supposed to work? It also doesn't work if I add it to each individual const, reporting each as unused next to the error I want to suppress.

@orklah
Copy link
Collaborator

orklah commented May 16, 2022

@AndrolGenhald That's weird, seems like the property is analyzed twice with two different values for the calculation

@AndrolGenhald
Copy link
Collaborator

AndrolGenhald commented May 16, 2022

Yeah, I've run into this before but most of the issues were fixed. I think the problem is that it's being resolved once by ClassLikeNodeScanner using SimpleTypeInferer to infer the type, then it's being resolved again when evaluating the assignment, and for some reason the assignment evaluation isn't as specific. I'll see if I can take a look at it this week.

@ricardoboss
Copy link
Contributor Author

If it helps: the order matters!

Moving the DAYS_PER_MONTH const above all others doesn't produce the error.

@AndrolGenhald
Copy link
Collaborator

As does moving SECONDS_PER_MONTH to the bottom, looks like the analysis isn't working correctly when constants are used before they're declared.

@ricardoboss
Copy link
Contributor Author

Apart from the consts, what about the psalm --alter suggestion? Is this just not implemented (yet)?

@AndrolGenhald AndrolGenhald self-assigned this May 16, 2022
@AndrolGenhald
Copy link
Collaborator

I'm not sure what's going on there, I don't think that issue should even be showing up as fixable. I'll look into that as well.

@AndrolGenhald
Copy link
Collaborator

AndrolGenhald commented May 20, 2022

Turns out the issue is in BinaryOpAnalyzer, it calculates literal expressions for ints but not for floats. The constant type inferrer gets the literal type when determining the constant's type, but then when the statement is later analyzed to make sure the assignment matches the constant's type it doesn't calculate the literal type, so it doesn't match. Working on a fix.

AndrolGenhald added a commit to AndrolGenhald/psalm that referenced this issue May 20, 2022
 vimeo#7973).

 - Calculate literal type for float arithmetic instead of only for int arithmetic
 - Fix copy/paste fail causing InvalidConstantAssignmentValue to be marked as fixable
orklah added a commit that referenced this issue May 21, 2022
Fix class const issue when using floats declared in future consts (fixes #7973).
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants