larastan / larastan

⚗️ Adds code analysis to Laravel improving developer productivity and code quality.
MIT License
5.49k stars 410 forks source link

Description of relationships #2071

Open choco-cat opened 1 day ago

choco-cat commented 1 day ago

Description

Hi. How to describe relationships correctly? To my description

    /**
     * @return BelongsTo<User, Rate>
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

an error occurs

 Method App\Rate\Models\Rate::user() should return Illuminate\Database\Eloquent\Relations\BelongsTo<App\Rate\Models\Rate<App\User\Models\User>> but returns
         Illuminate\Database\Eloquent\Relations\BelongsTo<App\User\Models\User, $this(App\Rate\Models\Rate)>.

Laravel code where the issue was found

    /**
     * @return BelongsTo<PariUser, Rate>
     */
    public function pariUser(): BelongsTo
    {
        return $this->belongsTo(PariUser::class);
    }
calebdw commented 1 day ago

This should be:

    /**
     * @return BelongsTo<User, $this>
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
calebdw commented 1 day ago

@canvural, I had new docs in #1990 that didn't get merged, can you cherry-pick that? 17bce5f783f19258312aaf8a45e3cbbec335b144

szepeviktor commented 1 day ago

Or just avoid the @return tag.

calebdw commented 1 day ago

Or just avoid the @return tag.

The @return is useful for IDE autocompletion on the method call---and you can avoid a costly model file parse if you include them

koraga commented 1 day ago

This should be:

    /**
     * @return BelongsTo<User, $this>
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

Same error:

    /**
     * @return BelongsTo<User, $this>
     */
    public function third(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }
Method App\Rate\Models\Rate::third() should return Illuminate\Database\Eloquent\Relations\BelongsTo<App\Admin\Models\User, App\Rate\Models\Rate> but   
         returns Illuminate\Database\Eloquent\Relations\BelongsTo<App\Admin\Models\User, $this(App\Rate\Models\Rate)>.                                          
         💡 Template type TDeclaringModel on class Illuminate\Database\Eloquent\Relations\BelongsTo is not covariant. Learn more:                               
            https://phpstan.org/blog/whats-up-with-template-covariant   
calebdw commented 1 day ago

Make sure to clear any cache, phpstan clear-result-cache

encodiaweb commented 1 day ago

Make sure to clear any cache, phpstan clear-result-cache

Thanks for this tip, but unfortunately, it didn't solve. Same errors as @koraga

koraga commented 1 day ago
    /**
     * @return BelongsTo<User, covariant $this>
     */
    public function user(): BelongsTo
    {
        return $this->belongsTo(User::class);
    }

There is no error if I add covariant

calebdw commented 1 day ago

Adding covariant is not the answer

This was working on #1990 (and it is working on my fork). Something likely was messed up when cherry-picking #1990

calebdw commented 1 day ago

What does the full Model look like? By any chance are they final?

koraga commented 1 day ago

What does the full Model look like? By any chance are they final?

Yes, all my models are final

calebdw commented 1 day ago

Yes, all my models are final

Ah, that's it---I can replicate it now. This looks like a PHPStan bug, I'll open an issue over there

davideprevosto commented 10 hours ago

My Models are not final, but I am getting the same issue.

calebdw commented 4 hours ago

@davideprevosto, then there's also a bug in Larastan because non-final models work just fine on my fork