Skip to content

MissingDependency with Carbon 3.x CarbonPeriod #11822

@AegirLeet

Description

@AegirLeet

composer require nesbot/carbon

Then create a test file like this:

<?php

declare(strict_types=1);

use Carbon\CarbonPeriod;

require __DIR__ . '/vendor/autoload.php';

$period = new CarbonPeriod();
echo $period->toString() . "\n";

Default config, generated by psalm --init:

psalm.xml
<?xml version="1.0"?>
<psalm
    errorLevel="1"
    resolveFromConfigFile="true"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns="https://getpsalm.org/schema/config"
    xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
    findUnusedBaselineEntry="true"
    findUnusedCode="true"
>
    <projectFiles>
        <file name="test.php" />
        <ignoreFiles>
            <directory name="vendor" />
        </ignoreFiles>
    </projectFiles>
</psalm>

And run Psalm. This results in several errors:

Psalm output
$ ./vendor/bin/psalm --no-cache

Running on PHP 8.4.20, Psalm 6.16.1@f1f5de594dc76faf8784e02d3dc4716c91c6f6ac.

JIT acceleration: OFF
You can enable JIT acceleration (experimental) with --force-jit.

Target PHP version: 8.4 (inferred from composer.json).


Scanning files...

283 / 283...

Analyzing files...

E

ERROR: MixedAssignment - test.php:10:1 - Unable to determine the type that $period is being assigned to (see https://psalm.dev/032)
$period = new CarbonPeriod();


ERROR: MissingDependency - test.php:10:15 - Carbon\CarbonPeriod depends on class or interface carbon\dateperiodbase that does not exist (see https://psalm.dev/157)
$period = new CarbonPeriod();


ERROR: MixedOperand - test.php:11:6 - Left operand cannot be mixed (see https://psalm.dev/059)
echo $period->toString() . "\n";


ERROR: MixedMethodCall - test.php:11:15 - Cannot determine the type of $period when calling method toString (see https://psalm.dev/015)
echo $period->toString() . "\n";

  The type of toString is sourced from here - test.php:10:1
$period = new CarbonPeriod();



------------------------------
4 errors found
------------------------------

Checks took 0.77 seconds and used 83.750MB of memory
Psalm was able to infer types for 40.0000% of the codebase

Seems related to these lines in Carbon https://github.com/briannesbitt/Carbon/blob/9b04563ba6a3fc04ed46d63c5718223d3900e88e/src/Carbon/CarbonPeriod.php#L50-L52 that load a different file based on the PHP version - the "missing" DatePeriodBase is declared there.

  • Manually doing require __DIR__ . '/vendor/nesbot/carbon/lazy/Carbon/UnprotectedDatePeriod.php'; fixes the issues. Not really a workable fix for any real project though.
  • Adding it to <stubs> in the config worked for this test file, but didn't work in a real project (not sure why)
  • Suppressing these issues is very difficult as it requires a @psalm-suppress MissingDependency for every line where the variable is used (the assignment and the echo in the example above)

I've had to resort to creating a baseline, which is a bit annoying.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions