Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

feat: add dynamic parameter type extensions #4290

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

Open
calebdw wants to merge 4 commits into phpstan:2.1.x
base: 2.1.x
Choose a base branch
Loading
from calebdw:dynamic_parameter_extension

Conversation

@calebdw
Copy link
Contributor

@calebdw calebdw commented Sep 5, 2025

Closes phpstan/phpstan#11707, closes phpstan/phpstan#12585

Supersedes #3828, supersedes #3131, supersedes #3823

Hello!

This adds generalized dynamic parameter type extensions and deprecates the parameter closure type extensions per phpstan/phpstan#11707 (comment).

This also fixes the return.type and the argument.type errors described in phpstan/phpstan#12585 when the parameter type is overridden via the extension.

Note

The original type from the closure type extensions was being passed around as $passedToType to the methods that needed it. However, with the new extensions the type must be passed around more, instead of adding parameter types to all the methods, I opted to add it to the ExpressionContext object that was already being passed around (given that this is context and whatnot) as overriddenType since I wasn't quite sure what $passedToType really meant. Let me know if there's something you'd rather do differently.

CC: @canvural, @Neol3108

Thanks!

Neol3108 and SanderMuller reacted with rocket emoji
@calebdw calebdw force-pushed the dynamic_parameter_extension branch 4 times, most recently from 49c7da8 to 58e51fb Compare September 5, 2025 14:15
@calebdw calebdw marked this pull request as draft September 5, 2025 16:35
@calebdw calebdw force-pushed the dynamic_parameter_extension branch from 58e51fb to 79de0a6 Compare September 5, 2025 17:05
@calebdw calebdw marked this pull request as ready for review September 5, 2025 17:36
Copy link
Collaborator

This pull request has been marked as ready for review.

Copy link
Contributor

canvural commented Sep 6, 2025

I tested it by porting my previous implementation for Larastan to this one, and looks like it works fine! Will try to implement more use cases and see if I can find any bugs. Also will try to test it on real projects.But so far so good. Thanks for this!

I'll also try to review this PR (though Ondrej would do a better job 😄 )

calebdw reacted with thumbs up emoji

@calebdw calebdw force-pushed the dynamic_parameter_extension branch from 79de0a6 to 7c605c1 Compare September 13, 2025 12:52
Copy link
Member

@ondrejmirtes ondrejmirtes left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This looks solid, just a few questions as a start, will do deep review later 👍

canvural reacted with heart emoji

declare(strict_types=1);

namespace App;
Copy link
Member

@ondrejmirtes ondrejmirtes Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure what the e2e/parameter-type-extension directory is for. These directories are supposed to execute something in .github/workflows/e2e-tests.yml but this one does not. Either move this under e2e/bug-12585/ if it's used there, or delete it.

private ?string $inAssignRightSideVariableName,
private ?Type $inAssignRightSideType,
private ?Type $inAssignRightSideNativeType,
private ?Type $overriddenType = null,
Copy link
Member

@ondrejmirtes ondrejmirtes Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does not have to be optional, this is not under BC promise.

return new self($this->isDeep, $this->inAssignRightSideVariableName, $this->inAssignRightSideType, $this->inAssignRightSideNativeType, $type);
}

public function getOverriddenType(): ?Type
Copy link
Member

@ondrejmirtes ondrejmirtes Sep 14, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why this does have to be here actually at all? Why hasn't been the passedToType parameter kept? Why is this named "overriden type"? What is it overriding?

Copy link
Contributor

canvural commented Oct 2, 2025

@calebdw @ondrejmirtes Sorry to bother you, but I wanted to ask how we can move this forward? I'm really interested in this feature.

Copy link
Contributor Author

calebdw commented Oct 2, 2025

No worries, just been busy with personal life, I'll try to get to the comments soon

Neol3108 reacted with hooray emoji canvural reacted with heart emoji

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Reviewers

@ondrejmirtes ondrejmirtes ondrejmirtes requested changes

Assignees

No one assigned

Labels

None yet

Projects

None yet

Milestone

No milestone

Development

Successfully merging this pull request may close these issues.

Invalid argument types when using MethodParameterClosureTypeExtension Allow specifying that parameters should be covariant

AltStyle によって変換されたページ (->オリジナル) /