-
Notifications
You must be signed in to change notification settings - Fork 7.6k
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
base: master
Are you sure you want to change the base?
Conversation
$TestVar1, $TestVar2 = "s1", "s2", "s3" | ||
$TestVar1 | ||
$TestVar2 | ||
}.Ast.FindAll({param($ast) $ast -is [Language.VariableExpressionAst]}, $true) | Select-Object -Last 2 |
There was a problem hiding this comment.
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[]
.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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
There was a problem hiding this comment.
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.
This pull request has been automatically marked as Review Needed because it has been there has not been any activity for 7 days. |
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
.h
,.cpp
,.cs
,.ps1
and.psm1
files have the correct copyright header