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

Class constants using other constants are mixed #1551

Closed
bugreportuser opened this issue Apr 13, 2019 · 4 comments
Closed

Class constants using other constants are mixed #1551

bugreportuser opened this issue Apr 13, 2019 · 4 comments
Labels

Comments

@bugreportuser
Copy link
Contributor

The type of Clazz::cons2 is int, but Psalm infers it as mixed.

Example (https://psalm.dev/r/f479e3cc0a):

<?php
const cons1 = 0;

class Clazz {
    const cons2 = cons1;
    const cons3 = 0;
}

echo cons1;
echo Clazz::cons2;
echo Clazz::cons3;

Example output:

Psalm output (using commit 21fd385):

INFO: MixedArgument - 10:6 - Argument 1 of echo cannot be mixed, expecting string

If this is a hard problem, #942 should fix it.

@muglug muglug added the bug label Apr 13, 2019
@TysonAndre
Copy link
Contributor

I'm not familiar with how psalm implements this.

One way to deal with this is to create a class to represent lazily loaded union type (with a closure that's called to resolve the value in the codebase), and only resolve the actual value of the union type the first time analysis needs to know the union type (which, most of the time, is after all of the classes are parsed)

@muglug
Copy link
Collaborator

muglug commented Apr 21, 2019

One way to deal with this is to create a class to represent lazily loaded union type

Psalm sort of does this for class constants from other classes - when it can’t immediately infer the type it stores the node, then tries again in the constant population stage.

@TysonAndre
Copy link
Contributor

Psalm sort of does this for class constants from other classes - when it can’t immediately infer the type it stores the node, then tries again in the constant population stage.

This approach is suggested for issues such as the below (haven't tested these - this is just for an idea of what I mean)

  • Subclasses inheriting a constant
  • Multiple layers of indirection
<?php
class A {
    const X = self::Y;
    const Y = 3;
}

class C extends B {
}

const Z = C::X;

class B extends A {
    const Z = self::X;
}

lhchavez added a commit to lhchavez/psalm that referenced this issue Aug 26, 2019
This change introduces the TMixedDeferredConstant type, which marks a
type as being a constant that needs to be resolved at a later stage.

Fixes: vimeo#1551
@muglug muglug closed this as completed in 0b4981f Sep 14, 2019
@bugreportuser
Copy link
Contributor Author

This is great! Thanks for the hard work!

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