Skip to content

Unexpected Behavior of return in Switch Block  #20739

Closed

Description

@danstur

Prerequisites

Steps to reproduce

Executing the following script in PowerShell 7.4.0 results in an unexpected behavior which also differs from PowerShell 5.1

function foo($x) {
    $val = switch ($x){
        1 { 5 }
        default {
            return 10 
        }
    }
    Write-Host "Val is $val" 
    $val + 1
}

Write-Host "foo 1: $(foo 1)"
Write-Host "foo 2: $(foo 2)"

PS 5.1 output:

Val is 5
foo 1: 6
foo 2: 10

PS 7.4.0 output:

Val is 5
foo 1: 6    
foo 2:

It's not clear if this is a bug or simply a documente change from classic PowerShell, but it certainly behaves in a way I don't find intuitive.

Expected behavior

PS> <execute script>
Val is 5
foo 1: 6
foo 2: 10

Actual behavior

PS> <execute script>
Val is 5
foo 1: 6
foo 2:

Error details

No response

Environment data

Name                           Value
----                           -----
PSVersion                      7.4.0
PSEdition                      Core
GitCommitId                    7.4.0
OS                             Microsoft Windows 10.0.19045
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0


Name                           Value
----                           -----
PSVersion                      5.1.19041.3570
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.3570
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1

Visuals

No response

Activity

  1. IISResetMe commented on Nov 21, 2023

    @IISResetMe
    Collaborator

    I have a feeling this isn't specific to switch statements - it appears the return expression ends up in the original assignment target when you return from any dot-sourced block:

    function f {
      try {
        $value = . { return 10 }
      }
      finally {
        Write-Host "`$Value is: '${Value}'"
      }
    }
    
    $returnValue = f
    Write-Host "Return value is: '${returnValue}'"
    
  2. danstur commented on Nov 21, 2023

    @danstur
    ContributorAuthor

    A colleague just ran the above script in 7.3.4 and there the behavior is identical to PS 5.1 - so this seems to be a bug that was introduced with 7.4.0.

  3. added
    Needs-InvestigationThe behavior reported in the issue is unexpected and needs further investigation.
    and removed
    Needs-TriageThe issue is new and needs to be triaged by a work group.
    on Nov 21, 2023
  4. mklement0 commented on Nov 21, 2023

    @mklement0
    Contributor

    The different behaviors can be demonstrated with the following simple command:

    $a = if ($true) { return 10 }
    • Windows PowerShell and PowerShell (Core) 7.3.x (presumably earlier too):
      • No assignment, outputs 10.
    • PowerShell 7.4.0:
      • No assignment, no output.

    That is, what the behaviors share is that no assignment takes place, but that there is no output in 7.4.0 is clearly a bug.

    The WinPS / PS 7.3- behavior may be surprising, but is defensible:

    • It is important to note that return does not exit just a { ... }-enclosed part of a language statement such as if or switch, but its enclosing function/script file/script block.

    • That is, the { ... } parts of such statements do not function like stand-alone script blocks such as the ones passed to ForEach-Object, in which return truly only exits that block.

    Therefore, in the original code the return immediately exits the whole function, with 7.4.0 inexplicably discarding the output.

  5. danstur commented on Nov 21, 2023

    @danstur
    ContributorAuthor

    Michael Klement (@mklement0) The behavior of 7.3.x and previous is what I'd intuitively expect to happen when reading the code.

  6. microsoft-github-policy-service commented on Mar 25, 2024

    @microsoft-github-policy-service
    Contributor

    📣 Hey Daniel Sturm (@danstur), how did we do? We would love to hear your feedback with the link below! 🗣️

    🔗 https://aka.ms/PSRepoFeedback

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    7.4-regressionRegression in 7.4In-PRIndicates that a PR is out for the issueNeeds-InvestigationThe behavior reported in the issue is unexpected and needs further investigation.WG-Enginecore PowerShell engine, interpreter, and runtimeWG-NeedsReviewNeeds a review by the labeled Working Group

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions