diff --git a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs index 5be3e414c7..9e26e4eff3 100644 --- a/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs +++ b/src/System.Management.Automation/engine/parser/TypeInferenceVisitor.cs @@ -2930,8 +2930,10 @@ namespace System.Management.Automation private void SetLastAssignment(Ast ast, bool enumerate = false, bool redirectionAssignment = false) { - if (LastAssignmentOffset < ast.Extent.StartOffset) + if (LastAssignmentOffset < ast.Extent.StartOffset && !VariableTarget.Extent.IsWithin(ast.Extent)) { + // If the variable we are inferring the value of is inside this assignment then the assignment is invalid + // For example: $x = Get-Random; $x = $x.Where{$_.} here the value should be inferred based on Get-Random and not $x = $x... ClearAssignmentData(); LastAssignment = ast; EnumerateAssignment = enumerate; diff --git a/test/powershell/engine/Api/TypeInference.Tests.ps1 b/test/powershell/engine/Api/TypeInference.Tests.ps1 index 4ba8ffd17d..5719c5c09a 100644 --- a/test/powershell/engine/Api/TypeInference.Tests.ps1 +++ b/test/powershell/engine/Api/TypeInference.Tests.ps1 @@ -1197,6 +1197,12 @@ Describe "Type inference Tests" -tags "CI" { $res.Name | Should -Be System.String } + It 'Ignores the last assignment when a variable is reused' { + $variableAst = { $x = New-Guid; $x = $x.Where{$_} }.Ast.FindAll({ param($a) $a -is [Language.VariableExpressionAst] }, $true) | select -Last 1 + $res = [AstTypeInference]::InferTypeOf($variableAst) + $res.Name | Should -Be System.Guid + } + $catchClauseTypes = @( @{ Type = 'System.ArgumentException' } @{ Type = 'System.ArgumentNullException' }