Skip to content

Conversation

liamduckett
Copy link
Contributor

Hey, resolves #3173 using param-closure-this.

@liamduckett
Copy link
Contributor Author

I had to alter the ignoreErrors entries for the Mixin trait, to accomodate this change. It doesn't get PHPStan issues to 0 - but does get them back to where they were before this PR.

I needed to swap:

'#^Undefined variable: \$this$#'
'#^Variable \$this in isset\(\) is never defined\.$#'

for

'#^Variable \$this in isset\(\) always exists and is not nullable\.$#'

This is because this (Macro|CarbonInterval)::macro method now believes $this is static. In reality this isn't actually true: given the rather unsual context in which this sits, $this could actually be static or undefined (for reference, it previously would have been though of as just undefined). I still believe this is the best path forward (despite having to ignore an error), as the situation in which $this is undefined is not exposed to userland code - and this change does resolve my original issue.

I think to resolve this properly (as in, without needing to ignore an error) - the logic that handles "whether we're in a static context" (see below) would need to rejigged. I think this would be out of the scope of this PR?

private static function loadMixinTrait(string $trait): void
{
    $context = eval(self::getAnonymousClassCodeForTrait($trait));
    $className = \get_class($context);
    $baseClass = static::class;

    foreach (self::getMixableMethods($context) as $name) {
        $closureBase = Closure::fromCallable([$context, $name]);

        static::macro($name, function (...$parameters) use ($closureBase, $className, $baseClass) {
            // This is the "whether we're in a static context" I'm referring to
            $downContext = isset($this) ? ($this) : new $baseClass();
            $context = isset($this) ? $this->cast($className) : new $className();
    // ...

I only added @param-closure-this to the methods that were required to satisfy PHPStan. In reality I think this should also be added to:

  1. src/Carbon/Factory::macro
  2. src/Carbon/CarbonInterface::macro
  3. src/Carbon/CarbonPeriod::macro

However I've left them out to keep the PR as slim as possible (feels slight pointless after writing this wall of text 😅) - happy to be directed otherwise.

Thanks!

@liamduckett
Copy link
Contributor Author

Failures all look unrelated to this PR?

@kylekatarnls
Copy link
Collaborator

Only the error ignore is to be removed from the phpstan config, the rest is fine.

@liamduckett
Copy link
Contributor Author

liamduckett commented Apr 6, 2025

I think the Laravel test failures are due to also unrelated? see this.

Edit: sorry I misread that - I'll look into the PHPStan error.

@liamduckett
Copy link
Contributor Author

I've resolved that PHPStan issue. It occurs (for me) on master (with none of my changes applied) - which is why I didn't do anything about it initially.

I can't immediately see how it could be related to my change?

@kylekatarnls kylekatarnls merged commit 2b73b87 into briannesbitt:master Apr 7, 2025
24 of 26 checks passed
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.

Incorrect Type Inference when Declaring Macros
2 participants