Stop setting $? to true for subpipelines and subexpressions#11040
Stop setting $? to true for subpipelines and subexpressions#11040daxian-dbw merged 14 commits intoPowerShell:masterfrom
Conversation
d6d8a55 to
58a5652
Compare
|
@rjmholt don't start writing a RFC for this, I believe after @PowerShell/powershell-committee review, it'll just be an update to your existing RFC |
test/powershell/Language/Operators/PipelineChainOperator.Tests.ps1
Outdated
Show resolved
Hide resolved
|
@rjmholt does this also affect the behaviour of |
Not currently. I can add tests so we can establish what the behaviour is and then should be. |
|
@vexx32 @KirkMunro are there any other expressions you can think of that could conceivably contain a statement? |
Brackets, array enclosures, subexpressions, and anonymous functions (script blocks that are dot-sourced or invoked) are the only things that come to mind for me. |
|
Yeah that's all I got, I think that about covers all the things we can do. Thanks for digging into this, Rob! 😊 💖 |
….ps1 Co-Authored-By: Ilya <darpa@yandex.ru>
|
@PowerShell/powershell-committee reviewed this and agree this is the correct behavior of |
| /// <returns>True is the compiler should add the success setting, false otherwise.</returns> | ||
| private bool MustSetSuccessAfterEvaluating(StatementAst statementAst) | ||
| { | ||
| // Simple overload fan out |
There was a problem hiding this comment.
Wanted to explain why this method really exists here -- it doesn't do anything itself, it's just for type resolution
|
One case I just thought of: Think for now we should leave it. Small (and strange) enough to address later. |
|
I would be perfectly happy to just set |
If you're embedding the results of a subexpression inside of a string, my initial reaction is that the outermost string-building should influence dollar-hook as it does now, because the string still gets built in that case, and that's what That said, should a scalar or string value ever influence dollar-hook? There isn't much value in that. |
Given that the string value is returned, I very much agree. Have added tests for that. |
|
🎉 Handy links: |
PR Summary
This PR alters the way we compile subpipelines
(...), subexpressions$(...)and array expressions@()so that$?is not automatically true after them in the pipeline, but instead depends on the pipeline or statements they executed.I've added tests for the various behaviours of this, plus some extra tests for pipeline chain operators, which this aids the UX of.
I've structured my changes by commit, so you'll probably find it easier to read this PR from commit to commit.
PR Context
In #9849, the
&&and||operators were introduced, but currently suffer from the implementation of$?. Specifically:This makes pipeline chain operators hard to use insofar as they can't be rearranged conveniently by means of parentheses.
In this PR, we change the implementation so that expression-only pipelines only have
$?forcibly set when they are a pure value, expressions that actually execute their commands with$?set by the subpipeline.Further considerations
Write-Errorfrom within another function still has that function leaving$?as true. I looked into changing that behaviour briefly and it would be fairly complicated.$?As a final note, looking into how to change this, it seems that while this behaviour may or may not have been originally intended, it occurs because we fix an assumption where all expressions in the pipeline are treated like pure expressions, which are optimised to be evaluated without the pipeline so need a
$? = $trueadded after them. So theoretically this change also is a small (very small) performance improvement.PR Checklist
.h,.cpp,.cs,.ps1and.psm1files have the correct copyright headerWIP:or[ WIP ]to the beginning of the title (theWIPbot will keep its status check atPendingwhile the prefix is present) and remove the prefix when the PR is ready.