Skip to content
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

return on the RHS of an assignment ignores the assignment #13146

Closed
mklement0 opened this issue Jul 9, 2020 · 13 comments
Closed

return on the RHS of an assignment ignores the assignment #13146

mklement0 opened this issue Jul 9, 2020 · 13 comments
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a

Comments

@mklement0
Copy link
Contributor

Note: This may be an exotic scenario that is easily avoided (no reason to ever use return this way), but I just came across it on Stack Overflow, and the behavior is surprising and unhelpful.

Steps to reproduce

# The assignment is *ignored* due to `return`, and the output goes straight to the success output stream.
$var = return 'foo'

$var | Should -BeExactly 'foo'

Expected behavior

The test should succeed.

Actual behavior

The test fails, because the assignment is ignored (the variable isn't even created) due to use of return.
The output goes straight to the success output stream and therefore prints to the display here.

Environment data

PowerShell Core 7.1.0-preview.5
@mklement0 mklement0 added the Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a label Jul 9, 2020
@SeeminglyScience
Copy link
Collaborator

SeeminglyScience commented Jul 9, 2020

The RHS is executed before any assignment happens. Works the same as any other flow control statement like $a = throw/$a = continue. Probably should have been a parse error when assignments started allowing statements on the RHS, though I'm not sure it'd be worth doing now. (Edit: wasn't a thing) (Edit 2: I don't know what's real anymore) Maybe a PSSA rule?

@rjmholt
Copy link
Collaborator

rjmholt commented Jul 9, 2020

As far as I know, assignment has always allowed full statements on the RHS. Because of this arrangement of the grammar, it would be very difficult, if not impossible, to turn this into a parse error. If nothing else, it would turn the RHS of assignments into a strange and confusing subset of the allowed statement grammar.

I'd say this is most like the old func_call(i++, i++) in C. It's syntactically allowed, but semantically not a good idea.

@mklement0
Copy link
Contributor Author

mklement0 commented Jul 9, 2020

Thanks, @SeeminglyScience and @rjmholt - I'm personally happy with a "won't-fix" / "as-designed" classification , but I wanted the potential pitfall recorded.

Perhaps a candidate for the docs wiki?

@mklement0
Copy link
Contributor Author

mklement0 commented Jul 9, 2020

I've updated the SO answer based on the feedback, so I'm happy to close this.

As an aside, @rjmholt: there is a second answer there that summarizes (and links to) our discussion in #10967 (using statements in pipelines / as expressions).

@SeeminglyScience
Copy link
Collaborator

As far as I know, assignment has always allowed full statements on the RHS.

I could have sworn there was a time back in the dark ages of v2 or 1 where you couldn't have an if statement on the RHS... Maybe I'm thinking of return statements? 🤷 anyway thanks for the correction ❤️

@daxian-dbw
Copy link
Member

I could have sworn there was a time back in the dark ages of v2 or 1 where you couldn't have an if statement on the RHS

@SeeminglyScience You are right, and it was relaxed to allow statement on the right hand side of assignment in v3.
A parsing error is possible by semantic checks, but may not be worth the effort.

@mklement0
Copy link
Contributor Author

Hmm... I just tried $var = if ($true) { 'yay' } and $var = foreach ($i in 1..10) { $i } in v2, and it worked.

However, something related is indeed broken, all the way up to v5.1 (fine since v6), although the scenario is very specific:

# Breaks in *Windows PowerShell* - OK in PowerShell Core.
@{
  Foo = if ($true) { "yes" } # Value is an `if` statement that LACKS AN `else` and there's NO OTHER ENTRY on the SAME LINE
  Bar = 'Baz' # !! Any key AFTER triggers the error
}

@SeeminglyScience
Copy link
Collaborator

@SeeminglyScience You are right, and it was relaxed to allow statement on the right hand side of assignment in v3.
A parsing error is possible by semantic checks, but may not be worth the effort.

See that's what I thought but then:

Hmm... I just tried $var = if ($true) { 'yay' } and $var = foreach ($i in 1..10) { $i } in v2, and it worked.

I tried it too with -verison 2 and it worked. I know there are some scenarios where -version 2 doesn't work exactly the same but I wouldn't have thought this would be one. You know if it was back ported? or maybe a change between 1 and 2?

At least I know I'm not crazy 😀

@mklement0
Copy link
Contributor Author

I know there are some scenarios where -version 2 doesn't work exactly the same

That's good to know (-version 2 is what I used too) - would have never occurred to me.

@SeeminglyScience
Copy link
Collaborator

That's good to know (-version 2 is what I used too) - would have never occurred to me.

Full disclosure, that's what I've heard. I don't remember anything specific or having ran into anything personally (though I also don't use it super often) so ymmv

@daxian-dbw
Copy link
Member

Hmm... I just tried $var = if ($true) { 'yay' } and $var = foreach ($i in 1..10) { $i } in v2, and it worked.

Ah, then I must remember it wrong. It could be a v1 -> v2 change. I doubt it would be ported back to v2 if it was done in v3, as v3 was a huge rewritten of a lot stuff.

However, something related is indeed broken, all the way up to v5.1 (fine since v6), although the scenario is very specific:

I think this one was fix by #7002

@mklement0
Copy link
Contributor Author

mklement0 commented Jul 9, 2020

Thanks, @daxian-dbw.

Can you tell us definitely if there can ever be a difference between running a later version with -version 2 and a stand-alone v2 version and, if so, what those difference are?

@daxian-dbw
Copy link
Member

daxian-dbw commented Jul 9, 2020

I don't think there is any difference between running a stand-alone v2 version and running powershell -v 2.
The reason to have powershell -v 2 was that there were breaking changes introduced in v3 and we needed a way for users to keep using v2 without worrying about anything broken. So by definition, it shouldn't allow any difference.

I believe the v2 assemblies that are in-box for powershell -v 2 to work were just a redistribution of those from a stand-alone v2 version. So, more precisely, there shouldn't be any difference code-wise.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Issue-Question ideally support can be provided via other mechanisms, but sometimes folks do open an issue to get a
Projects
None yet
Development

No branches or pull requests

4 participants