8000 Infer variables assigned in ArrayLiterals and ParenExpressions by MartinGC94 · Pull Request #25317 · PowerShell/PowerShell · GitHub
[go: up one dir, main page]

Skip to content

Infer variables assigned in ArrayLiterals and ParenExpressions #25317

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
wants to merge 2 commits into
base: master
Choose a base branch
from

Conversation

MartinGC94
Copy link
Contributor

PR Summary

Similar fix as this one: #25303 this time it's for the type inference so that variables assigned in ArrayLiterals like: $Var1, $Var2 = 1..10 are inferred properly. And the same for variables inside ParenExpressions: ($Var1) = 1..10.

PR Context

PR Checklist

$TestVar1, $TestVar2 = "s1", "s2", "s3"
$TestVar1
$TestVar2
}.Ast.FindAll({param($ast) $ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 2
Copy link
Collaborator

Choose a reason for hiding this comment

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

I played with:

$Asts = {
            $TestVar1, $TestVar2, $TestVar3 = $(New-Guid), "s2", 1, 2, 3
            $TestVar1
            $TestVar2
            $TestVar3
        }.Ast.FindAll({param($ast) $ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 3

and got System.Object, System.Object and System.Object[] but expected System.Guid, System.String and System.Int32[].

Copy link
Contributor Author

Choose a reason for hiding this comment

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

That's working as expected. The RHS is evaluated as a whole, and because it's a mixed set of objects, we consider it an Object[] that is then deconstructed to Object for the first set of variables.
I don't think it's worth the effort to fix this. We could only feasibly fix this for constants like in your example, but if you are working with constants then there's no reason to declare them like this.

Copy link
Collaborator

Choose a reason for hiding this comment

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

These can be not only constants, but also everything that type inference works for.
It is a common in pwsh that the right side is a list of objects of the same type, but it is in the decomposition scenario that we rather expect these objects to be of different types. Decomposition has great features in pwsh. I think it deserves more support.
Since we iterate over variables in a loop, we can easily check the type at the appropriate position on the right side (if it supports indexing, of course) and even slice to get the rest.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I have added it for array literals on the RHS. There is no practical way to do this without making a lot of changes to the rest of the inference code to handle dynamic expressions on the RHS, so this:

$Array = "string", 42
$String, $Number = $Array

Would infer the variables as object and object[] just like before.

Copy link
Collaborator

Choose a reason for hiding this comment

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

This raises the question of usefulness and expediency. The current approach is rather a workaround for a limited number of scenarios. In other cases, it provides useless information or even false information. Even if I accept your first commit, I'm afraid it will raise questions about why it doesn't always work. Perhaps this is the case when it is better to do nothing at all if it is impossible to provide deconstruction support with reasonable efforts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is not a feature I use, but for the people that do use it, do you think it's common to mix types like that where it would cause issues? I'd imagine the most common use case would be something like: $FirstItem, $TheRest = Get-Something or maybe something like: $Index, $OtherNumbers = 1..10.
I don't imagine people tend to mix and match completely unrelated types in one array that they then split up with this syntax.

If people do want to mix and match, they can just add a type constraint and it will work as expected (thanks to the changes in this PR):

$Array = "string", 42
[string]$String, [int]$Number = $Array

Copy link
Collaborator

Choose a reason for hiding this comment

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

do you think it's common to mix types like that where it would cause issues?

I can't say for sure, but that was the first thing I thought of when looking at your new tests. It can also be used to pass anonymous parameters to a function, followed by deconstruction. Finally, it can be used in Lisp-style programming. I don't think all this is super popular, but it's possible just because of the weak support in the pwsh ecosystem.

@microsoft-github-policy-service microsoft-github-policy-service bot added the Review - Needed The PR is being reviewed label Apr 20, 2025
8000 @microsoft-github-policy-service Microsoft GitHub Policy Service
Copy link
Contributor

This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days.
Maintainer, please provide feedback and/or mark it as Waiting on Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Review - Needed The PR is being reviewed
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants
0