diff --git a/src/System.Management.Automation/engine/parser/Compiler.cs b/src/System.Management.Automation/engine/parser/Compiler.cs
index fcae018bd..327001181 100644
--- a/src/System.Management.Automation/engine/parser/Compiler.cs
+++ b/src/System.Management.Automation/engine/parser/Compiler.cs
@@ -3200,7 +3200,7 @@ namespace System.Management.Automation.Language
ExpressionCache.Constant(0)));
tryBodyExprs.Add(Expression.Label(label0));
tryBodyExprs.Add(Expression.Assign(dispatchIndex, ExpressionCache.Constant(1)));
- tryBodyExprs.Add(Compile(currentChain.LhsPipelineChain));
+ tryBodyExprs.Add(CompilePipelineChainElement((PipelineAst)currentChain.LhsPipelineChain));
// Remainder of try statement body
// L1: dispatchIndex = 2; if ($?) pipeline2;
@@ -3234,7 +3234,7 @@ namespace System.Management.Automation.Language
? s_getDollarQuestion
: s_notDollarQuestion;
- tryBodyExprs.Add(Expression.IfThen(dollarQuestionCheck, Compile(currentChain.RhsPipeline)));
+ tryBodyExprs.Add(Expression.IfThen(dollarQuestionCheck, CompilePipelineChainElement(currentChain.RhsPipeline)));
currentChain = currentChain.Parent as PipelineChainAst;
}
@@ -3277,6 +3277,24 @@ namespace System.Management.Automation.Language
return fullyExpandedBlock;
}
+ ///
+ /// Compile a pipeline as an element in a pipeline chain.
+ /// Needed since pure expressions won't set $? after them.
+ /// which does something similar.
+ ///
+ /// The pipeline in the pipeline chain to compile to an expression.
+ /// The compiled expression to execute the pipeline.
+ private Expression CompilePipelineChainElement(PipelineAst pipelineAst)
+ {
+ if (pipelineAst.PipelineElements.Count == 1 && pipelineAst.PipelineElements[0] is CommandExpressionAst)
+ {
+ // A single expression - must set $? after the expression.
+ return Expression.Block(Compile(pipelineAst), s_setDollarQuestionToTrue);
+ }
+
+ return Compile(pipelineAst);
+ }
+
public object VisitPipeline(PipelineAst pipelineAst)
{
var temps = new List();
diff --git a/src/System.Management.Automation/engine/parser/token.cs b/src/System.Management.Automation/engine/parser/token.cs
index b9dae289e..62d911baa 100644
--- a/src/System.Management.Automation/engine/parser/token.cs
+++ b/src/System.Management.Automation/engine/parser/token.cs
@@ -790,8 +790,8 @@ namespace System.Management.Automation.Language
#region Flags for operators
- /* AndAnd */ TokenFlags.BinaryOperator | TokenFlags.ParseModeInvariant,
- /* OrOr */ TokenFlags.BinaryOperator | TokenFlags.ParseModeInvariant,
+ /* AndAnd */ TokenFlags.ParseModeInvariant,
+ /* OrOr */ TokenFlags.ParseModeInvariant,
/* Ampersand */ TokenFlags.SpecialOperator | TokenFlags.ParseModeInvariant,
/* Pipe */ TokenFlags.SpecialOperator | TokenFlags.ParseModeInvariant,
/* Comma */ TokenFlags.UnaryOperator | TokenFlags.ParseModeInvariant,
diff --git a/test/powershell/Language/Operators/PipelineChainOperator.Tests.ps1 b/test/powershell/Language/Operators/PipelineChainOperator.Tests.ps1
index d376161f3..2e8242a47 100644
--- a/test/powershell/Language/Operators/PipelineChainOperator.Tests.ps1
+++ b/test/powershell/Language/Operators/PipelineChainOperator.Tests.ps1
@@ -76,6 +76,8 @@ Describe "Experimental Feature: && and || operators - Feature-Enabled" -Tag CI {
@{ Statement = '"hi" && testexe -returncode 1'; Output = @('hi', '1') }
@{ Statement = 'testexe -returncode 1 && "Hi"'; Output = @('1') }
@{ Statement = 'testexe -returncode 1 || "hi"'; Output = @('1', 'hi') }
+ @{ Statement = '"hello" && get-item macarena_doesnotexist || "there"; "hello" || "there"'; Output = @('hello', 'there', 'hello') }
+ @{ Statement = '1 + 1 && "Hi"'; Output = @(2, 'Hi') }
# Pipeline and native command
@{ Statement = '1,2,3 | % { $_ + 1 } && testexe -returncode 0'; Output = @('2','3','4','0') }