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

psalm-pure invalid error #8625

Closed
kkmuffme opened this issue Oct 27, 2022 · 8 comments
Closed

psalm-pure invalid error #8625

kkmuffme opened this issue Oct 27, 2022 · 8 comments

Comments

@kkmuffme
Copy link
Contributor

https://psalm.dev/docs/annotating_code/supported_annotations/#:~:text=one%20whose%20output%20is%20just%20a%20function%20of%20its%20input

one whose output is just a function of its input

https://psalm.dev/r/dff3f37215 the output of abc() is pure, as it only depends on the input given (= always returns the same output for same input and has no side-effects) - but it still reports an error for it?

Are the docs wrong/am I misunderstanding "purity"? Or is this a bug?

@psalm-github-bot
Copy link

I found these snippets:

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

/**
 * @psalm-pure
 *
 * @return Hello
 */
function abc() {
    $xyz = new Hello();
    $xyz->world = true;
    return $xyz;
}

class Hello {
  public bool $world = false;
}
Psalm output (using commit 7c83878):

ERROR: ImpurePropertyAssignment - 10:5 - Cannot assign to a property from a mutation-free context

@orklah
Copy link
Collaborator

orklah commented Oct 27, 2022

It is the no side-effects thing that prevents you from setting this attribute.

With no additional annotation, this could happen:
https://psalm.dev/r/413d60d78e
https://3v4l.org/R0RLT

So Psalm must forbid you to modify attributes when precautions are not taken. However, you could use @psalm-external-mutation-free in order to inform Psalm that there is no mutation outside of the scope of the object: https://psalm.dev/r/97334d3fc9

Psalm will then allow you to change this attribute

@psalm-github-bot
Copy link

I found these snippets:

https://psalm.dev/r/413d60d78e
<?php

/**
 * @psalm-pure
 *
 * @return Hello
 */
function abc() {
    $xyz = new Hello();
    $xyz->world = true;
    return $xyz;
}

class Hello {
  public function __set($param, $value){
   	echo "This is a major side effect!";   
  }
}
Psalm output (using commit 7c83878):

ERROR: ImpureMethodCall - 10:11 - Cannot call a non-mutation-free method Hello::__set from a pure context

ERROR: ImpurePropertyAssignment - 10:5 - Cannot assign to a property from a mutation-free context

INFO: MissingParamType - 15:25 - Parameter $param has no provided type

INFO: MissingParamType - 15:33 - Parameter $value has no provided type
https://psalm.dev/r/97334d3fc9
<?php

/**
 * @psalm-pure
 *
 * @return Hello
 */
function abc() {
    $xyz = new Hello();
    $xyz->world = true;
    return $xyz;
}

/** @psalm-external-mutation-free */
class Hello {
  public bool $world = false;
}
Psalm output (using commit 7c83878):

No issues!

@kkmuffme
Copy link
Contributor Author

But I do not have a __set method in class Hello and psalm is aware of it. Where is the side-effect in the given example?

@orklah
Copy link
Collaborator

orklah commented Oct 27, 2022

Your object is not final, so __set could still be defined in a child that would not be known by Psalm (but it seems like even with final, Psalm doesn't allow it)

I guess we could add handling for setting a property on an object if:

  • it was created locally
  • the instance doesn't leave the current scope
  • it's final
  • it doesn't have __set
  • the property is not static
  • it doesn't have any __destruct
  • we don't do anything else with the object that may persist it

I think I covered every possibility! Or you could flag the object external-mutation-free and help Psalm a little 😄

@kkmuffme
Copy link
Contributor Author

The problem is with #8624 - bc of this false positive, how do you suggest to handle this never type? (without completely reworking the type combiner, which eats the never type, making this property necessary in the first place)

@orklah
Copy link
Collaborator

orklah commented Oct 28, 2022

Do you have a snippet to show how this is related to never? I really struggle to grasp what's bugging you here

@kkmuffme
Copy link
Contributor Author

Issue solved itself as the underlying stuff in psalm was changed/fixed

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

2 participants