diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs b/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs deleted file mode 100644 index 68fed229791af..0000000000000 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundLoweredIsPatternExpression.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Licensed to the .NET Foundation under one or more agreements. -// The .NET Foundation licenses this file to you under the MIT license. -// See the LICENSE file in the project root for more information. - -using System.Diagnostics; - -namespace Microsoft.CodeAnalysis.CSharp; - -partial class BoundLoweredIsPatternExpression -{ - private partial void Validate() - { - // Ensure fall-through is unreachable - Debug.Assert(this.Statements is [.., BoundGotoStatement or BoundSwitchDispatch]); - } -} diff --git a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml index 02d74f70ecc62..88e6637761223 100644 --- a/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml +++ b/src/Compilers/CSharp/Portable/BoundTree/BoundNodes.xml @@ -2323,7 +2323,6 @@ 'is not Type t') will need to compensate for negated patterns. IsNegated is set if Pattern is the negated form of the inner pattern represented by DecisionDag. --> - @@ -2332,13 +2331,6 @@ - - - - - - - diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs index a59e96c2d03b7..e01696b8940d5 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitExpression.cs @@ -315,10 +315,6 @@ private void EmitExpressionCore(BoundExpression expression, bool used) EmitRefValueOperator((BoundRefValueOperator)expression, used); break; - case BoundKind.LoweredIsPatternExpression: - EmitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)expression, used); - break; - case BoundKind.LoweredConditionalAccess: EmitLoweredConditionalAccessExpression((BoundLoweredConditionalAccess)expression, used); break; @@ -356,42 +352,6 @@ private void EmitExpressionCore(BoundExpression expression, bool used) } } - private void EmitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, bool used, bool sense = true) - { - EmitSideEffects(node.Statements); - - if (!used) - { - _builder.MarkLabel(node.WhenTrueLabel); - _builder.MarkLabel(node.WhenFalseLabel); - } - else - { - var doneLabel = new object(); - _builder.MarkLabel(node.WhenTrueLabel); - _builder.EmitBoolConstant(sense); - _builder.EmitBranch(ILOpCode.Br, doneLabel); - _builder.AdjustStack(-1); - _builder.MarkLabel(node.WhenFalseLabel); - _builder.EmitBoolConstant(!sense); - _builder.MarkLabel(doneLabel); - } - } - - private void EmitSideEffects(ImmutableArray statements) - { -#if DEBUG - int prevStack = _expectedStackDepth; - int origStack = _builder.GetStackDepth(); - _expectedStackDepth = origStack; -#endif - EmitStatements(statements); -#if DEBUG - Debug.Assert(_expectedStackDepth == origStack); - _expectedStackDepth = prevStack; -#endif - } - private void EmitThrowExpression(BoundThrowExpression node, bool used) { this.EmitThrow(node.Expression); @@ -870,7 +830,7 @@ private void EmitSequencePoint(BoundSequencePointExpression node) } } - private void EmitSequenceExpression(BoundSequence sequence, bool used, bool sense = true) + private void EmitSequenceExpression(BoundSequence sequence, bool used) { DefineLocals(sequence); EmitSideEffects(sequence); @@ -884,14 +844,7 @@ private void EmitSequenceExpression(BoundSequence sequence, bool used, bool sens Debug.Assert(sequence.Value.Kind != BoundKind.TypeExpression || !used); if (sequence.Value.Kind != BoundKind.TypeExpression) { - if (used && sequence.Type.SpecialType == SpecialType.System_Boolean) - { - EmitCondExpr(sequence.Value, sense: sense); - } - else - { - EmitExpression(sequence.Value, used: used); - } + EmitExpression(sequence.Value, used); } // sequence is used as a value, can release all locals diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs index ee3f158d49eca..80ca057d83076 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitOperators.cs @@ -484,25 +484,14 @@ private void EmitCondExpr(BoundExpression condition, bool sense) return; } - switch (condition.Kind) + if (condition.Kind == BoundKind.BinaryOperator) { - case BoundKind.BinaryOperator: - var binOp = (BoundBinaryOperator)condition; - if (!IsConditional(binOp.OperatorKind)) - { - break; - } - + var binOp = (BoundBinaryOperator)condition; + if (IsConditional(binOp.OperatorKind)) + { EmitBinaryCondOperator(binOp, sense); return; - - case BoundKind.Sequence: - EmitSequenceExpression((BoundSequence)condition, used: true, sense); - return; - - case BoundKind.LoweredIsPatternExpression: - EmitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)condition, used: true, sense); - return; + } } EmitExpression(condition, true); diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs index c10b5e3b01a77..a1de22a4eaebb 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs @@ -24,10 +24,6 @@ namespace Microsoft.CodeAnalysis.CSharp.CodeGen { internal partial class CodeGenerator { -#if DEBUG - private int _expectedStackDepth = 0; -#endif - private void EmitStatement(BoundStatement statement) { switch (statement.Kind) @@ -112,7 +108,7 @@ private void EmitStatement(BoundStatement statement) #if DEBUG if (_stackLocals == null || _stackLocals.Count == 0) { - _builder.AssertStackDepth(_expectedStackDepth); + _builder.AssertStackEmpty(); } #endif @@ -576,28 +572,6 @@ top.condition is BoundBinaryOperator binary && } return; - case BoundKind.LoweredIsPatternExpression: - { - var loweredIs = (BoundLoweredIsPatternExpression)condition; - dest ??= new object(); - - EmitSideEffects(loweredIs.Statements); - - if (sense) - { - _builder.MarkLabel(loweredIs.WhenTrueLabel); - _builder.EmitBranch(ILOpCode.Br, dest); - _builder.MarkLabel(loweredIs.WhenFalseLabel); - } - else - { - _builder.MarkLabel(loweredIs.WhenFalseLabel); - _builder.EmitBranch(ILOpCode.Br, dest); - _builder.MarkLabel(loweredIs.WhenTrueLabel); - } - } - return; - case BoundKind.UnaryOperator: var unOp = (BoundUnaryOperator)condition; if (unOp.OperatorKind == UnaryOperatorKind.BoolLogicalNegation) diff --git a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs index 0c886bd35f0d2..1f78697ed6dbf 100644 --- a/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs +++ b/src/Compilers/CSharp/Portable/CodeGen/Optimizer.cs @@ -415,10 +415,6 @@ internal sealed class StackOptimizerPass1 : BoundTreeRewriter private int _recursionDepth; -#if DEBUG - private int _expectedStackDepth = 0; -#endif - private StackOptimizerPass1(Dictionary locals, ArrayBuilder> evalStack, bool debugFriendly) @@ -569,27 +565,10 @@ private void PopEvalStack() public BoundNode VisitStatement(BoundNode node) { -#if DEBUG - Debug.Assert(node == null || StackDepth() == _expectedStackDepth); -#endif + Debug.Assert(node == null || EvalStackIsEmpty()); return VisitSideEffect(node); } - public ImmutableArray VisitSideEffects(ImmutableArray statements) - { -#if DEBUG - int prevStack = _expectedStackDepth; - int origStack = StackDepth(); - _expectedStackDepth = origStack; -#endif - var result = this.VisitList(statements); -#if DEBUG - Debug.Assert(_expectedStackDepth == origStack); - _expectedStackDepth = prevStack; -#endif - return result; - } - public BoundNode VisitSideEffect(BoundNode node) { var origStack = StackDepth(); @@ -1437,6 +1416,8 @@ public override BoundNode VisitConditionalGoto(BoundConditionalGoto node) public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) { + Debug.Assert(EvalStackIsEmpty()); + // switch dispatch needs a byval local or a parameter as a key. // if this is already a fitting local, let's keep it that way BoundExpression boundExpression = node.Expression; @@ -1466,14 +1447,6 @@ public override BoundNode VisitSwitchDispatch(BoundSwitchDispatch node) return node.Update(boundExpression, node.Cases, node.DefaultLabel, node.LengthBasedStringSwitchDataOpt); } - public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) - { - var statements = VisitSideEffects(node.Statements); - RecordBranch(node.WhenTrueLabel); - RecordBranch(node.WhenFalseLabel); - return node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, VisitType(node.Type)); - } - public override BoundNode VisitConditionalOperator(BoundConditionalOperator node) { var origStack = StackDepth(); diff --git a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs index 5587fada10819..f6ad3e6b993ba 100644 --- a/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs +++ b/src/Compilers/CSharp/Portable/FlowAnalysis/AbstractFlowPass.cs @@ -3031,12 +3031,6 @@ public override BoundNode VisitConditionalReceiver(BoundConditionalReceiver node return null; } - public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) - { - VisitStatements(node.Statements); - return null; - } - public override BoundNode VisitComplexConditionalReceiver(BoundComplexConditionalReceiver node) { var savedState = this.State.Clone(); diff --git a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs index 7e1b6bb1e4fd1..ad861489a6f94 100644 --- a/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs +++ b/src/Compilers/CSharp/Portable/Generated/BoundNodes.xml.Generated.cs @@ -225,7 +225,6 @@ internal enum BoundKind : byte InterpolatedStringArgumentPlaceholder, StringInsert, IsPatternExpression, - LoweredIsPatternExpression, ConstantPattern, DiscardPattern, DeclarationPattern, @@ -7786,7 +7785,7 @@ public BoundStringInsert Update(BoundExpression value, BoundExpression? alignmen internal sealed partial class BoundIsPatternExpression : BoundExpression { - public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type, bool hasErrors = false) + public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol? type, bool hasErrors = false) : base(BoundKind.IsPatternExpression, syntax, type, hasErrors || expression.HasErrors() || pattern.HasErrors() || reachabilityDecisionDag.HasErrors()) { @@ -7795,7 +7794,6 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B RoslynDebug.Assert(reachabilityDecisionDag is object, "Field 'reachabilityDecisionDag' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); RoslynDebug.Assert(whenTrueLabel is object, "Field 'whenTrueLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); RoslynDebug.Assert(whenFalseLabel is object, "Field 'whenFalseLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); - RoslynDebug.Assert(type is object, "Field 'type' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); this.Expression = expression; this.Pattern = pattern; @@ -7805,7 +7803,6 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B this.WhenFalseLabel = whenFalseLabel; } - public new TypeSymbol Type => base.Type!; public BoundExpression Expression { get; } public BoundPattern Pattern { get; } public bool IsNegated { get; } @@ -7816,7 +7813,7 @@ public BoundIsPatternExpression(SyntaxNode syntax, BoundExpression expression, B [DebuggerStepThrough] public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitIsPatternExpression(this); - public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type) + public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern pattern, bool isNegated, BoundDecisionDag reachabilityDecisionDag, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol? type) { if (expression != this.Expression || pattern != this.Pattern || isNegated != this.IsNegated || reachabilityDecisionDag != this.ReachabilityDecisionDag || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenTrueLabel, this.WhenTrueLabel) || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenFalseLabel, this.WhenFalseLabel) || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything)) { @@ -7828,46 +7825,6 @@ public BoundIsPatternExpression Update(BoundExpression expression, BoundPattern } } - internal sealed partial class BoundLoweredIsPatternExpression : BoundExpression - { - public BoundLoweredIsPatternExpression(SyntaxNode syntax, ImmutableArray statements, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type, bool hasErrors = false) - : base(BoundKind.LoweredIsPatternExpression, syntax, type, hasErrors || statements.HasErrors()) - { - - RoslynDebug.Assert(!statements.IsDefault, "Field 'statements' cannot be null (use Null=\"allow\" in BoundNodes.xml to remove this check)"); - RoslynDebug.Assert(whenTrueLabel is object, "Field 'whenTrueLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); - RoslynDebug.Assert(whenFalseLabel is object, "Field 'whenFalseLabel' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); - RoslynDebug.Assert(type is object, "Field 'type' cannot be null (make the type nullable in BoundNodes.xml to remove this check)"); - - this.Statements = statements; - this.WhenTrueLabel = whenTrueLabel; - this.WhenFalseLabel = whenFalseLabel; - Validate(); - } - - [Conditional("DEBUG")] - private partial void Validate(); - - public new TypeSymbol Type => base.Type!; - public ImmutableArray Statements { get; } - public LabelSymbol WhenTrueLabel { get; } - public LabelSymbol WhenFalseLabel { get; } - - [DebuggerStepThrough] - public override BoundNode? Accept(BoundTreeVisitor visitor) => visitor.VisitLoweredIsPatternExpression(this); - - public BoundLoweredIsPatternExpression Update(ImmutableArray statements, LabelSymbol whenTrueLabel, LabelSymbol whenFalseLabel, TypeSymbol type) - { - if (statements != this.Statements || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenTrueLabel, this.WhenTrueLabel) || !Symbols.SymbolEqualityComparer.ConsiderEverything.Equals(whenFalseLabel, this.WhenFalseLabel) || !TypeSymbol.Equals(type, this.Type, TypeCompareKind.ConsiderEverything)) - { - var result = new BoundLoweredIsPatternExpression(this.Syntax, statements, whenTrueLabel, whenFalseLabel, type, this.HasErrors); - result.CopyAttributes(this); - return result; - } - return this; - } - } - internal abstract partial class BoundPattern : BoundNode { protected BoundPattern(BoundKind kind, SyntaxNode syntax, TypeSymbol inputType, TypeSymbol narrowedType, bool hasErrors) @@ -9123,8 +9080,6 @@ internal R VisitInternal(BoundNode node, A arg) return VisitStringInsert((BoundStringInsert)node, arg); case BoundKind.IsPatternExpression: return VisitIsPatternExpression((BoundIsPatternExpression)node, arg); - case BoundKind.LoweredIsPatternExpression: - return VisitLoweredIsPatternExpression((BoundLoweredIsPatternExpression)node, arg); case BoundKind.ConstantPattern: return VisitConstantPattern((BoundConstantPattern)node, arg); case BoundKind.DiscardPattern: @@ -9384,7 +9339,6 @@ internal abstract partial class BoundTreeVisitor public virtual R VisitInterpolatedStringArgumentPlaceholder(BoundInterpolatedStringArgumentPlaceholder node, A arg) => this.DefaultVisit(node, arg); public virtual R VisitStringInsert(BoundStringInsert node, A arg) => this.DefaultVisit(node, arg); public virtual R VisitIsPatternExpression(BoundIsPatternExpression node, A arg) => this.DefaultVisit(node, arg); - public virtual R VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, A arg) => this.DefaultVisit(node, arg); public virtual R VisitConstantPattern(BoundConstantPattern node, A arg) => this.DefaultVisit(node, arg); public virtual R VisitDiscardPattern(BoundDiscardPattern node, A arg) => this.DefaultVisit(node, arg); public virtual R VisitDeclarationPattern(BoundDeclarationPattern node, A arg) => this.DefaultVisit(node, arg); @@ -9617,7 +9571,6 @@ internal abstract partial class BoundTreeVisitor public virtual BoundNode? VisitInterpolatedStringArgumentPlaceholder(BoundInterpolatedStringArgumentPlaceholder node) => this.DefaultVisit(node); public virtual BoundNode? VisitStringInsert(BoundStringInsert node) => this.DefaultVisit(node); public virtual BoundNode? VisitIsPatternExpression(BoundIsPatternExpression node) => this.DefaultVisit(node); - public virtual BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) => this.DefaultVisit(node); public virtual BoundNode? VisitConstantPattern(BoundConstantPattern node) => this.DefaultVisit(node); public virtual BoundNode? VisitDiscardPattern(BoundDiscardPattern node) => this.DefaultVisit(node); public virtual BoundNode? VisitDeclarationPattern(BoundDeclarationPattern node) => this.DefaultVisit(node); @@ -10542,11 +10495,6 @@ internal abstract partial class BoundTreeWalker : BoundTreeVisitor this.Visit(node.Pattern); return null; } - public override BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) - { - this.VisitList(node.Statements); - return null; - } public override BoundNode? VisitConstantPattern(BoundConstantPattern node) { this.Visit(node.Value); @@ -11894,12 +11842,6 @@ internal abstract partial class BoundTreeRewriter : BoundTreeVisitor TypeSymbol? type = this.VisitType(node.Type); return node.Update(expression, pattern, node.IsNegated, reachabilityDecisionDag, node.WhenTrueLabel, node.WhenFalseLabel, type); } - public override BoundNode? VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) - { - ImmutableArray statements = this.VisitList(node.Statements); - TypeSymbol? type = this.VisitType(node.Type); - return node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, type); - } public override BoundNode? VisitConstantPattern(BoundConstantPattern node) { BoundExpression value = (BoundExpression)this.Visit(node.Value); @@ -14519,7 +14461,7 @@ public NullabilityRewriter(ImmutableDictionary statements = this.VisitList(node.Statements); - BoundLoweredIsPatternExpression updatedNode; - - if (_updatedNullabilities.TryGetValue(node, out (NullabilityInfo Info, TypeSymbol? Type) infoAndType)) - { - updatedNode = node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, infoAndType.Type!); - updatedNode.TopLevelNullability = infoAndType.Info; - } - else - { - updatedNode = node.Update(statements, node.WhenTrueLabel, node.WhenFalseLabel, node.Type); - } - return updatedNode; - } - public override BoundNode? VisitConstantPattern(BoundConstantPattern node) { TypeSymbol inputType = GetUpdatedSymbol(node, node.InputType); @@ -16706,16 +16631,6 @@ private BoundTreeDumperNodeProducer() new TreeDumperNode("hasErrors", node.HasErrors, null) } ); - public override TreeDumperNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node, object? arg) => new TreeDumperNode("loweredIsPatternExpression", null, new TreeDumperNode[] - { - new TreeDumperNode("statements", null, from x in node.Statements select Visit(x, null)), - new TreeDumperNode("whenTrueLabel", node.WhenTrueLabel, null), - new TreeDumperNode("whenFalseLabel", node.WhenFalseLabel, null), - new TreeDumperNode("type", node.Type, null), - new TreeDumperNode("isSuppressed", node.IsSuppressed, null), - new TreeDumperNode("hasErrors", node.HasErrors, null) - } - ); public override TreeDumperNode VisitConstantPattern(BoundConstantPattern node, object? arg) => new TreeDumperNode("constantPattern", null, new TreeDumperNode[] { new TreeDumperNode("value", null, new TreeDumperNode[] { Visit(node.Value, null) }), diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs index 00cbbd7362677..753a242ab44fc 100644 --- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs +++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_IsPatternOperator.cs @@ -108,32 +108,29 @@ public IsPatternExpressionGeneralLocalRewriter( internal BoundExpression LowerGeneralIsPattern(BoundIsPatternExpression node, BoundDecisionDag decisionDag) { - Debug.Assert(node.Type is { SpecialType: SpecialType.System_Boolean }); - _factory.Syntax = node.Syntax; + var resultBuilder = ArrayBuilder.GetInstance(); var inputExpression = _localRewriter.VisitExpression(node.Expression); - var sideEffectsBuilder = ArrayBuilder.GetInstance(); - - // The optimization of sharing pattern-matching temps with user variables can always apply to - // an is-pattern expression because there is no when clause that could possibly intervene during - // the execution of the pattern-matching automaton and change one of those variables. - decisionDag = ShareTempsAndEvaluateInput(inputExpression, decisionDag, sideEffectsBuilder.Add, out _); + decisionDag = ShareTempsIfPossibleAndEvaluateInput(decisionDag, inputExpression, resultBuilder, out _); // lower the decision dag. ImmutableArray loweredDag = LowerDecisionDagCore(decisionDag); - var resultBuilder = ArrayBuilder.GetInstance(loweredDag.Length + _statements.Count); - resultBuilder.AddRange(loweredDag); - resultBuilder.AddRange(_statements); - return _factory.Sequence( - _tempAllocator.AllTemps(), - sideEffectsBuilder.ToImmutableAndFree(), - new BoundLoweredIsPatternExpression( - node.Syntax, - // Note: it is not expected for this node to trigger spilling - resultBuilder.ToImmutableAndFree(), - node.WhenTrueLabel, - node.WhenFalseLabel, - node.Type)); + resultBuilder.Add(_factory.Block(loweredDag)); + Debug.Assert(node.Type is { SpecialType: SpecialType.System_Boolean }); + LocalSymbol resultTemp = _factory.SynthesizedLocal(node.Type, node.Syntax, kind: SynthesizedLocalKind.LoweringTemp); + LabelSymbol afterIsPatternExpression = _factory.GenerateLabel("afterIsPatternExpression"); + LabelSymbol trueLabel = node.WhenTrueLabel; + LabelSymbol falseLabel = node.WhenFalseLabel; + if (_statements.Count != 0) + resultBuilder.Add(_factory.Block(_statements.ToArray())); + resultBuilder.Add(_factory.Label(trueLabel)); + resultBuilder.Add(_factory.Assignment(_factory.Local(resultTemp), _factory.Literal(true))); + resultBuilder.Add(_factory.Goto(afterIsPatternExpression)); + resultBuilder.Add(_factory.Label(falseLabel)); + resultBuilder.Add(_factory.Assignment(_factory.Local(resultTemp), _factory.Literal(false))); + resultBuilder.Add(_factory.Label(afterIsPatternExpression)); + _localRewriter._needsSpilling = true; + return _factory.SpillSequence(_tempAllocator.AllTemps().Add(resultTemp), resultBuilder.ToImmutableAndFree(), _factory.Local(resultTemp)); } } diff --git a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs index 9acb45ac30e19..dfe215468f343 100644 --- a/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs +++ b/src/Compilers/CSharp/Portable/Lowering/SpillSequenceSpiller.cs @@ -716,16 +716,6 @@ public override BoundNode DefaultVisit(BoundNode node) #region Expression Visitors -#if DEBUG - public override BoundNode VisitLoweredIsPatternExpression(BoundLoweredIsPatternExpression node) - { - // Ensure this node won't trigger spilling - var result = base.VisitLoweredIsPatternExpression(node); - Debug.Assert(result == node); - return result; - } -#endif - public override BoundNode VisitAwaitExpression(BoundAwaitExpression node) { // An await expression has already been wrapped in a BoundSpillSequence if not at the top level, so diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs index 3ea415841744d..caad6cb2b227c 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/PatternTests.cs @@ -3003,7 +3003,7 @@ public class NotPossibleException : System.Exception { } var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("ConsoleApp1.TestHelper.IsValueTypeT(ConsoleApp1.Result)", @"{ - // Code size 28 (0x1c) + // Code size 31 (0x1f) .maxstack 2 .locals init (T V_0, //v bool V_1) @@ -3014,13 +3014,15 @@ .locals init (T V_0, //v IL_0008: ldloc.0 IL_0009: box ""T"" IL_000e: ldnull - IL_000f: ceq - IL_0011: stloc.1 - IL_0012: ldloc.1 - IL_0013: brfalse.s IL_001b - IL_0015: newobj ""ConsoleApp1.NotPossibleException..ctor()"" - IL_001a: throw - IL_001b: ret + IL_000f: cgt.un + IL_0011: ldc.i4.0 + IL_0012: ceq + IL_0014: stloc.1 + IL_0015: ldloc.1 + IL_0016: brfalse.s IL_001e + IL_0018: newobj ""ConsoleApp1.NotPossibleException..ctor()"" + IL_001d: throw + IL_001e: ret }"); } @@ -5517,19 +5519,23 @@ public static void Main() var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", """ { - // Code size 23 (0x17) + // Code size 26 (0x1a) .maxstack 1 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: isinst "int" IL_0006: brtrue.s IL_0012 IL_0008: ldarg.0 IL_0009: isinst "long" IL_000e: brtrue.s IL_0012 - IL_0010: br.s IL_0015 + IL_0010: br.s IL_0016 IL_0012: ldc.i4.1 - IL_0013: br.s IL_0016 - IL_0015: ldc.i4.0 - IL_0016: ret + IL_0013: stloc.0 + IL_0014: br.s IL_0018 + IL_0016: ldc.i4.0 + IL_0017: stloc.0 + IL_0018: ldloc.0 + IL_0019: ret } """); compVerifier.VerifyIL("C.M2", """ @@ -5554,18 +5560,22 @@ .maxstack 2 compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", """ { - // Code size 20 (0x14) + // Code size 24 (0x18) .maxstack 1 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: isinst "int" IL_0006: brtrue.s IL_0010 IL_0008: ldarg.0 IL_0009: isinst "long" - IL_000e: brfalse.s IL_0012 + IL_000e: brfalse.s IL_0014 IL_0010: ldc.i4.1 - IL_0011: ret - IL_0012: ldc.i4.0 - IL_0013: ret + IL_0011: stloc.0 + IL_0012: br.s IL_0016 + IL_0014: ldc.i4.0 + IL_0015: stloc.0 + IL_0016: ldloc.0 + IL_0017: ret } """); compVerifier.VerifyIL("C.M2", @" @@ -5609,20 +5619,27 @@ public static void Main() var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", """ { - // Code size 33 (0x21) + // Code size 40 (0x28) .maxstack 1 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: isinst "int" IL_0006: brtrue.s IL_0012 IL_0008: ldarg.0 IL_0009: isinst "long" IL_000e: brtrue.s IL_0012 - IL_0010: br.s IL_0014 - IL_0012: br.s IL_001b - IL_0014: ldstr "False" - IL_0019: br.s IL_0020 - IL_001b: ldstr "True" - IL_0020: ret + IL_0010: br.s IL_0016 + IL_0012: ldc.i4.1 + IL_0013: stloc.0 + IL_0014: br.s IL_0018 + IL_0016: ldc.i4.0 + IL_0017: stloc.0 + IL_0018: ldloc.0 + IL_0019: brtrue.s IL_0022 + IL_001b: ldstr "False" + IL_0020: br.s IL_0027 + IL_0022: ldstr "True" + IL_0027: ret } """); compVerifier.VerifyIL("C.M2", """ @@ -5647,18 +5664,26 @@ .maxstack 1 compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", """ { - // Code size 28 (0x1c) + // Code size 37 (0x25) .maxstack 1 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: isinst "int" - IL_0006: brtrue.s IL_0016 + IL_0006: brtrue.s IL_0010 IL_0008: ldarg.0 IL_0009: isinst "long" - IL_000e: brtrue.s IL_0016 - IL_0010: ldstr "False" - IL_0015: ret - IL_0016: ldstr "True" - IL_001b: ret + IL_000e: brfalse.s IL_0014 + IL_0010: ldc.i4.1 + IL_0011: stloc.0 + IL_0012: br.s IL_0016 + IL_0014: ldc.i4.0 + IL_0015: stloc.0 + IL_0016: ldloc.0 + IL_0017: brtrue.s IL_001f + IL_0019: ldstr "False" + IL_001e: ret + IL_001f: ldstr "True" + IL_0024: ret } """); compVerifier.VerifyIL("C.M2", @" @@ -5702,12 +5727,13 @@ public static void Main() var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 44 (0x2c) + // Code size 47 (0x2f) .maxstack 2 - .locals init (char V_0) + .locals init (char V_0, + bool V_1) IL_0000: ldarg.0 IL_0001: isinst ""char"" - IL_0006: brfalse.s IL_002a + IL_0006: brfalse.s IL_002b IL_0008: ldarg.0 IL_0009: unbox.any ""char"" IL_000e: stloc.0 @@ -5717,18 +5743,21 @@ .locals init (char V_0) IL_0014: ldloc.0 IL_0015: ldc.i4.s 122 IL_0017: ble.s IL_0027 - IL_0019: br.s IL_002a + IL_0019: br.s IL_002b IL_001b: ldloc.0 IL_001c: ldc.i4.s 65 - IL_001e: blt.s IL_002a + IL_001e: blt.s IL_002b IL_0020: ldloc.0 IL_0021: ldc.i4.s 90 IL_0023: ble.s IL_0027 - IL_0025: br.s IL_002a + IL_0025: br.s IL_002b IL_0027: ldc.i4.1 - IL_0028: br.s IL_002b - IL_002a: ldc.i4.0 - IL_002b: ret + IL_0028: stloc.1 + IL_0029: br.s IL_002d + IL_002b: ldc.i4.0 + IL_002c: stloc.1 + IL_002d: ldloc.1 + IL_002e: ret } "); compVerifier.VerifyIL("C.M2", @" @@ -5771,12 +5800,13 @@ .locals init (char V_0) //c compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 41 (0x29) + // Code size 45 (0x2d) .maxstack 2 - .locals init (char V_0) + .locals init (char V_0, + bool V_1) IL_0000: ldarg.0 IL_0001: isinst ""char"" - IL_0006: brfalse.s IL_0027 + IL_0006: brfalse.s IL_0029 IL_0008: ldarg.0 IL_0009: unbox.any ""char"" IL_000e: stloc.0 @@ -5786,17 +5816,20 @@ .locals init (char V_0) IL_0014: ldloc.0 IL_0015: ldc.i4.s 122 IL_0017: ble.s IL_0025 - IL_0019: br.s IL_0027 + IL_0019: br.s IL_0029 IL_001b: ldloc.0 IL_001c: ldc.i4.s 65 - IL_001e: blt.s IL_0027 + IL_001e: blt.s IL_0029 IL_0020: ldloc.0 IL_0021: ldc.i4.s 90 - IL_0023: bgt.s IL_0027 + IL_0023: bgt.s IL_0029 IL_0025: ldc.i4.1 - IL_0026: ret - IL_0027: ldc.i4.0 - IL_0028: ret + IL_0026: stloc.1 + IL_0027: br.s IL_002b + IL_0029: ldc.i4.0 + IL_002a: stloc.1 + IL_002b: ldloc.1 + IL_002c: ret } "); compVerifier.VerifyIL("C.M2", @" @@ -5858,27 +5891,34 @@ public static void Main() var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 31 (0x1f) + // Code size 38 (0x26) .maxstack 2 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: ldc.i4.s 97 IL_0003: blt.s IL_000c IL_0005: ldarg.0 IL_0006: ldc.i4.s 122 IL_0008: ble.s IL_0018 - IL_000a: br.s IL_001a + IL_000a: br.s IL_001c IL_000c: ldarg.0 IL_000d: ldc.i4.s 65 - IL_000f: blt.s IL_001a + IL_000f: blt.s IL_001c IL_0011: ldarg.0 IL_0012: ldc.i4.s 90 IL_0014: ble.s IL_0018 - IL_0016: br.s IL_001a - IL_0018: br.s IL_001d - IL_001a: ldc.i4.0 - IL_001b: br.s IL_001e - IL_001d: ldc.i4.1 - IL_001e: ret + IL_0016: br.s IL_001c + IL_0018: ldc.i4.1 + IL_0019: stloc.0 + IL_001a: br.s IL_001e + IL_001c: ldc.i4.0 + IL_001d: stloc.0 + IL_001e: ldloc.0 + IL_001f: brtrue.s IL_0024 + IL_0021: ldc.i4.0 + IL_0022: br.s IL_0025 + IL_0024: ldc.i4.1 + IL_0025: ret } "); compVerifier.VerifyIL("C.M2", @" @@ -5909,27 +5949,31 @@ .maxstack 2 compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 30 (0x1e) + // Code size 33 (0x21) .maxstack 2 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: ldc.i4.s 97 IL_0003: blt.s IL_000c IL_0005: ldarg.0 IL_0006: ldc.i4.s 122 IL_0008: ble.s IL_0016 - IL_000a: br.s IL_0019 + IL_000a: br.s IL_001a IL_000c: ldarg.0 IL_000d: ldc.i4.s 65 - IL_000f: blt.s IL_0019 + IL_000f: blt.s IL_001a IL_0011: ldarg.0 IL_0012: ldc.i4.s 90 - IL_0014: bgt.s IL_0019 + IL_0014: bgt.s IL_001a IL_0016: ldc.i4.1 - IL_0017: br.s IL_001a - IL_0019: ldc.i4.0 + IL_0017: stloc.0 + IL_0018: br.s IL_001c IL_001a: ldc.i4.0 - IL_001b: cgt.un - IL_001d: ret + IL_001b: stloc.0 + IL_001c: ldloc.0 + IL_001d: ldc.i4.0 + IL_001e: cgt.un + IL_0020: ret } "); compVerifier.VerifyIL("C.M2", @" @@ -5991,10 +6035,11 @@ public static void Main() var compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 43 (0x2b) + // Code size 46 (0x2e) .maxstack 2 .locals init (bool V_0, - int V_1) + bool V_1, + int V_2) IL_0000: nop IL_0001: ldarg.0 IL_0002: ldc.i4.s 97 @@ -6002,28 +6047,31 @@ .locals init (bool V_0, IL_0006: ldarg.0 IL_0007: ldc.i4.s 122 IL_0009: ble.s IL_0019 - IL_000b: br.s IL_001c + IL_000b: br.s IL_001d IL_000d: ldarg.0 IL_000e: ldc.i4.s 65 - IL_0010: blt.s IL_001c + IL_0010: blt.s IL_001d IL_0012: ldarg.0 IL_0013: ldc.i4.s 90 IL_0015: ble.s IL_0019 - IL_0017: br.s IL_001c + IL_0017: br.s IL_001d IL_0019: ldc.i4.1 - IL_001a: br.s IL_001d - IL_001c: ldc.i4.0 - IL_001d: stloc.0 - IL_001e: ldloc.0 - IL_001f: brfalse.s IL_0025 - IL_0021: ldc.i4.1 - IL_0022: stloc.1 - IL_0023: br.s IL_0029 - IL_0025: ldc.i4.0 - IL_0026: stloc.1 - IL_0027: br.s IL_0029 - IL_0029: ldloc.1 - IL_002a: ret + IL_001a: stloc.0 + IL_001b: br.s IL_001f + IL_001d: ldc.i4.0 + IL_001e: stloc.0 + IL_001f: ldloc.0 + IL_0020: stloc.1 + IL_0021: ldloc.1 + IL_0022: brfalse.s IL_0028 + IL_0024: ldc.i4.1 + IL_0025: stloc.2 + IL_0026: br.s IL_002c + IL_0028: ldc.i4.0 + IL_0029: stloc.2 + IL_002a: br.s IL_002c + IL_002c: ldloc.2 + IL_002d: ret } "); compVerifier.VerifyIL("C.M2", @" @@ -6070,25 +6118,33 @@ .locals init (bool V_0, compVerifier = CompileAndVerify(compilation, expectedOutput: expectedOutput); compVerifier.VerifyIL("C.M1", @" { - // Code size 26 (0x1a) + // Code size 35 (0x23) .maxstack 2 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: ldc.i4.s 97 IL_0003: blt.s IL_000c IL_0005: ldarg.0 IL_0006: ldc.i4.s 122 IL_0008: ble.s IL_0016 - IL_000a: br.s IL_0018 + IL_000a: br.s IL_001a IL_000c: ldarg.0 IL_000d: ldc.i4.s 65 - IL_000f: blt.s IL_0018 + IL_000f: blt.s IL_001a IL_0011: ldarg.0 IL_0012: ldc.i4.s 90 - IL_0014: bgt.s IL_0018 + IL_0014: bgt.s IL_001a IL_0016: ldc.i4.1 - IL_0017: ret - IL_0018: ldc.i4.0 - IL_0019: ret + IL_0017: stloc.0 + IL_0018: br.s IL_001c + IL_001a: ldc.i4.0 + IL_001b: stloc.0 + IL_001c: ldloc.0 + IL_001d: brfalse.s IL_0021 + IL_001f: ldc.i4.1 + IL_0020: ret + IL_0021: ldc.i4.0 + IL_0022: ret } "); compVerifier.VerifyIL("C.M2", @" diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs index 36a18e4d686d6..80639c18b5aee 100644 --- a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs +++ b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs @@ -7125,7 +7125,7 @@ .maxstack 2 IL_0760: ret }"; compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning", codeForSwitchStatement); - compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_IsExpression", codeForSwitchStatement); + compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_IsExpression", codeForExpression); compVerifier.VerifyIL("ConsoleApplication24.Program.IsWarning_SwitchExpression", codeForExpression); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs index b6a2d27997430..079528fbe3997 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests.cs @@ -8354,63 +8354,64 @@ static void Test(ReadOnlySpan chars) not: True") .VerifyIL("C.Test", """ { - // Code size 166 (0xa6) + // Code size 167 (0xa7) .maxstack 3 .locals init (bool V_0) IL_0000: nop - IL_0001: ldstr "or: " - IL_0006: ldarg.0 - IL_0007: ldstr "string 1" - IL_000c: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0011: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" - IL_0016: brtrue.s IL_002c - IL_0018: ldarg.0 - IL_0019: ldstr "string 2" - IL_001e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0023: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" - IL_0028: brtrue.s IL_002c - IL_002a: br.s IL_002f - IL_002c: ldc.i4.1 - IL_002d: br.s IL_0030 - IL_002f: ldc.i4.0 - IL_0030: stloc.0 - IL_0031: ldloca.s V_0 - IL_0033: call "string bool.ToString()" - IL_0038: call "string string.Concat(string, string)" - IL_003d: call "void System.Console.WriteLine(string)" - IL_0042: nop - IL_0043: ldstr "and: " - IL_0048: ldarg.0 - IL_0049: ldstr "string 1" - IL_004e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0053: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" - IL_0058: brfalse.s IL_0066 - IL_005a: ldarga.s V_0 - IL_005c: call "int System.ReadOnlySpan.Length.get" - IL_0061: ldc.i4.7 - IL_0062: ceq - IL_0064: br.s IL_0067 - IL_0066: ldc.i4.0 - IL_0067: stloc.0 - IL_0068: ldloca.s V_0 - IL_006a: call "string bool.ToString()" - IL_006f: call "string string.Concat(string, string)" - IL_0074: call "void System.Console.WriteLine(string)" - IL_0079: nop - IL_007a: ldstr "not: " - IL_007f: ldarg.0 - IL_0080: ldstr "string 1" - IL_0085: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_008a: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" - IL_008f: ldc.i4.0 - IL_0090: ceq - IL_0092: stloc.0 - IL_0093: ldloca.s V_0 - IL_0095: call "string bool.ToString()" - IL_009a: call "string string.Concat(string, string)" - IL_009f: call "void System.Console.WriteLine(string)" - IL_00a4: nop - IL_00a5: ret + IL_0001: ldarg.0 + IL_0002: ldstr "string 1" + IL_0007: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_000c: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" + IL_0011: brtrue.s IL_0027 + IL_0013: ldarg.0 + IL_0014: ldstr "string 2" + IL_0019: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_001e: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" + IL_0023: brtrue.s IL_0027 + IL_0025: br.s IL_002b + IL_0027: ldc.i4.1 + IL_0028: stloc.0 + IL_0029: br.s IL_002d + IL_002b: ldc.i4.0 + IL_002c: stloc.0 + IL_002d: ldstr "or: " + IL_0032: ldloca.s V_0 + IL_0034: call "string bool.ToString()" + IL_0039: call "string string.Concat(string, string)" + IL_003e: call "void System.Console.WriteLine(string)" + IL_0043: nop + IL_0044: ldstr "and: " + IL_0049: ldarg.0 + IL_004a: ldstr "string 1" + IL_004f: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_0054: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" + IL_0059: brfalse.s IL_0067 + IL_005b: ldarga.s V_0 + IL_005d: call "int System.ReadOnlySpan.Length.get" + IL_0062: ldc.i4.7 + IL_0063: ceq + IL_0065: br.s IL_0068 + IL_0067: ldc.i4.0 + IL_0068: stloc.0 + IL_0069: ldloca.s V_0 + IL_006b: call "string bool.ToString()" + IL_0070: call "string string.Concat(string, string)" + IL_0075: call "void System.Console.WriteLine(string)" + IL_007a: nop + IL_007b: ldstr "not: " + IL_0080: ldarg.0 + IL_0081: ldstr "string 1" + IL_0086: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_008b: call "bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)" + IL_0090: ldc.i4.0 + IL_0091: ceq + IL_0093: stloc.0 + IL_0094: ldloca.s V_0 + IL_0096: call "string bool.ToString()" + IL_009b: call "string string.Concat(string, string)" + IL_00a0: call "void System.Console.WriteLine(string)" + IL_00a5: nop + IL_00a6: ret } """); } @@ -8919,14 +8920,14 @@ .locals init (bool V_0) IL_0066: call ""string bool.ToString()"" IL_006b: call ""string string.Concat(string, string)"" IL_0070: call ""void System.Console.WriteLine(string)"" - IL_0075: ldstr ""4."" - IL_007a: ldarg.0 - IL_007b: ldstr """" - IL_0080: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" - IL_0085: call ""bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"" - IL_008a: pop - IL_008b: ldc.i4.1 - IL_008c: stloc.0 + IL_0075: ldarg.0 + IL_0076: ldstr """" + IL_007b: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" + IL_0080: call ""bool System.MemoryExtensions.SequenceEqual(System.ReadOnlySpan, System.ReadOnlySpan)"" + IL_0085: pop + IL_0086: ldc.i4.1 + IL_0087: stloc.0 + IL_0088: ldstr ""4."" IL_008d: ldloca.s V_0 IL_008f: call ""string bool.ToString()"" IL_0094: call ""string string.Concat(string, string)"" @@ -9951,63 +9952,64 @@ static void Test(Span chars) not: True") .VerifyIL("C.Test", """ { - // Code size 166 (0xa6) + // Code size 167 (0xa7) .maxstack 3 .locals init (bool V_0) IL_0000: nop - IL_0001: ldstr "or: " - IL_0006: ldarg.0 - IL_0007: ldstr "string 1" - IL_000c: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0011: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" - IL_0016: brtrue.s IL_002c - IL_0018: ldarg.0 - IL_0019: ldstr "string 2" - IL_001e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0023: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" - IL_0028: brtrue.s IL_002c - IL_002a: br.s IL_002f - IL_002c: ldc.i4.1 - IL_002d: br.s IL_0030 - IL_002f: ldc.i4.0 - IL_0030: stloc.0 - IL_0031: ldloca.s V_0 - IL_0033: call "string bool.ToString()" - IL_0038: call "string string.Concat(string, string)" - IL_003d: call "void System.Console.WriteLine(string)" - IL_0042: nop - IL_0043: ldstr "and: " - IL_0048: ldarg.0 - IL_0049: ldstr "string 1" - IL_004e: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_0053: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" - IL_0058: brfalse.s IL_0066 - IL_005a: ldarga.s V_0 - IL_005c: call "int System.Span.Length.get" - IL_0061: ldc.i4.7 - IL_0062: ceq - IL_0064: br.s IL_0067 - IL_0066: ldc.i4.0 - IL_0067: stloc.0 - IL_0068: ldloca.s V_0 - IL_006a: call "string bool.ToString()" - IL_006f: call "string string.Concat(string, string)" - IL_0074: call "void System.Console.WriteLine(string)" - IL_0079: nop - IL_007a: ldstr "not: " - IL_007f: ldarg.0 - IL_0080: ldstr "string 1" - IL_0085: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" - IL_008a: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" - IL_008f: ldc.i4.0 - IL_0090: ceq - IL_0092: stloc.0 - IL_0093: ldloca.s V_0 - IL_0095: call "string bool.ToString()" - IL_009a: call "string string.Concat(string, string)" - IL_009f: call "void System.Console.WriteLine(string)" - IL_00a4: nop - IL_00a5: ret + IL_0001: ldarg.0 + IL_0002: ldstr "string 1" + IL_0007: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_000c: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" + IL_0011: brtrue.s IL_0027 + IL_0013: ldarg.0 + IL_0014: ldstr "string 2" + IL_0019: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_001e: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" + IL_0023: brtrue.s IL_0027 + IL_0025: br.s IL_002b + IL_0027: ldc.i4.1 + IL_0028: stloc.0 + IL_0029: br.s IL_002d + IL_002b: ldc.i4.0 + IL_002c: stloc.0 + IL_002d: ldstr "or: " + IL_0032: ldloca.s V_0 + IL_0034: call "string bool.ToString()" + IL_0039: call "string string.Concat(string, string)" + IL_003e: call "void System.Console.WriteLine(string)" + IL_0043: nop + IL_0044: ldstr "and: " + IL_0049: ldarg.0 + IL_004a: ldstr "string 1" + IL_004f: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_0054: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" + IL_0059: brfalse.s IL_0067 + IL_005b: ldarga.s V_0 + IL_005d: call "int System.Span.Length.get" + IL_0062: ldc.i4.7 + IL_0063: ceq + IL_0065: br.s IL_0068 + IL_0067: ldc.i4.0 + IL_0068: stloc.0 + IL_0069: ldloca.s V_0 + IL_006b: call "string bool.ToString()" + IL_0070: call "string string.Concat(string, string)" + IL_0075: call "void System.Console.WriteLine(string)" + IL_007a: nop + IL_007b: ldstr "not: " + IL_0080: ldarg.0 + IL_0081: ldstr "string 1" + IL_0086: call "System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)" + IL_008b: call "bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)" + IL_0090: ldc.i4.0 + IL_0091: ceq + IL_0093: stloc.0 + IL_0094: ldloca.s V_0 + IL_0096: call "string bool.ToString()" + IL_009b: call "string string.Concat(string, string)" + IL_00a0: call "void System.Console.WriteLine(string)" + IL_00a5: nop + IL_00a6: ret } """); } @@ -10521,14 +10523,14 @@ .locals init (bool V_0) IL_0066: call ""string bool.ToString()"" IL_006b: call ""string string.Concat(string, string)"" IL_0070: call ""void System.Console.WriteLine(string)"" - IL_0075: ldstr ""4."" - IL_007a: ldarg.0 - IL_007b: ldstr """" - IL_0080: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" - IL_0085: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" - IL_008a: pop - IL_008b: ldc.i4.1 - IL_008c: stloc.0 + IL_0075: ldarg.0 + IL_0076: ldstr """" + IL_007b: call ""System.ReadOnlySpan System.MemoryExtensions.AsSpan(string)"" + IL_0080: call ""bool System.MemoryExtensions.SequenceEqual(System.Span, System.ReadOnlySpan)"" + IL_0085: pop + IL_0086: ldc.i4.1 + IL_0087: stloc.0 + IL_0088: ldstr ""4."" IL_008d: ldloca.s V_0 IL_008f: call ""string bool.ToString()"" IL_0094: call ""string string.Concat(string, string)"" @@ -11589,16 +11591,16 @@ public static async Task ExceptionFilterBroken() // in the exception filter (at IL_00b6) before accessing `.InnerException` on it. verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" { - // Code size 460 (0x1cc) + // Code size 471 (0x1d7) .maxstack 3 .locals init (int V_0, bool V_1, - System.Runtime.CompilerServices.TaskAwaiter V_2, - C.d__1 V_3, - System.Exception V_4, - bool V_5, - System.Exception V_6, - string V_7, + System.Exception V_2, + string V_3, + bool V_4, + System.Runtime.CompilerServices.TaskAwaiter V_5, + C.d__1 V_6, + System.Exception V_7, int V_8, System.Runtime.CompilerServices.TaskAwaiter V_9) IL_0000: ldarg.0 @@ -11614,7 +11616,7 @@ .locals init (int V_0, IL_000e: beq.s IL_0014 IL_0010: br.s IL_0019 IL_0012: br.s IL_0021 - IL_0014: br IL_0159 + IL_0014: br IL_0166 IL_0019: nop IL_001a: ldarg.0 IL_001b: ldc.i4.0 @@ -11625,188 +11627,193 @@ .locals init (int V_0, IL_0022: ldloc.0 IL_0023: brfalse.s IL_0027 IL_0025: br.s IL_0029 - IL_0027: br.s IL_0065 + IL_0027: br.s IL_0068 IL_0029: nop IL_002a: call ""System.Threading.Tasks.Task C.ThrowException()"" IL_002f: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0034: stloc.2 - IL_0035: ldloca.s V_2 - IL_0037: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_003c: brtrue.s IL_0081 - IL_003e: ldarg.0 - IL_003f: ldc.i4.0 - IL_0040: dup - IL_0041: stloc.0 - IL_0042: stfld ""int C.d__1.<>1__state"" - IL_0047: ldarg.0 - IL_0048: ldloc.2 - IL_0049: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" - IL_004e: ldarg.0 - IL_004f: stloc.3 + IL_0034: stloc.s V_5 + IL_0036: ldloca.s V_5 + IL_0038: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" + IL_003d: brtrue.s IL_0085 + IL_003f: ldarg.0 + IL_0040: ldc.i4.0 + IL_0041: dup + IL_0042: stloc.0 + IL_0043: stfld ""int C.d__1.<>1__state"" + IL_0048: ldarg.0 + IL_0049: ldloc.s V_5 + IL_004b: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" IL_0050: ldarg.0 - IL_0051: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_0056: ldloca.s V_2 - IL_0058: ldloca.s V_3 - IL_005a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" - IL_005f: nop - IL_0060: leave IL_01cb - IL_0065: ldarg.0 - IL_0066: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" - IL_006b: stloc.2 - IL_006c: ldarg.0 - IL_006d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" - IL_0072: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0078: ldarg.0 - IL_0079: ldc.i4.m1 - IL_007a: dup - IL_007b: stloc.0 - IL_007c: stfld ""int C.d__1.<>1__state"" - IL_0081: ldloca.s V_2 - IL_0083: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_0088: nop - IL_0089: ldc.i4.1 - IL_008a: stloc.1 - IL_008b: leave IL_01b6 + IL_0051: stloc.s V_6 + IL_0053: ldarg.0 + IL_0054: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0059: ldloca.s V_5 + IL_005b: ldloca.s V_6 + IL_005d: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" + IL_0062: nop + IL_0063: leave IL_01d6 + IL_0068: ldarg.0 + IL_0069: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" + IL_006e: stloc.s V_5 + IL_0070: ldarg.0 + IL_0071: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" + IL_0076: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_007c: ldarg.0 + IL_007d: ldc.i4.m1 + IL_007e: dup + IL_007f: stloc.0 + IL_0080: stfld ""int C.d__1.<>1__state"" + IL_0085: ldloca.s V_5 + IL_0087: call ""void System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_008c: nop + IL_008d: ldc.i4.1 + IL_008e: stloc.1 + IL_008f: leave IL_01c1 } filter { - IL_0090: isinst ""System.Exception"" - IL_0095: dup - IL_0096: brtrue.s IL_009c - IL_0098: pop - IL_0099: ldc.i4.0 - IL_009a: br.s IL_00fa - IL_009c: stloc.s V_4 - IL_009e: ldarg.0 - IL_009f: ldloc.s V_4 - IL_00a1: stfld ""object C.d__1.<>s__1"" - IL_00a6: ldarg.0 - IL_00a7: ldarg.0 - IL_00a8: ldfld ""object C.d__1.<>s__1"" - IL_00ad: castclass ""System.Exception"" - IL_00b2: stfld ""System.Exception C.d__1.5__3"" - IL_00b7: ldarg.0 - IL_00b8: ldfld ""System.Exception C.d__1.5__3"" - IL_00bd: callvirt ""System.Exception System.Exception.InnerException.get"" - IL_00c2: stloc.s V_6 - IL_00c4: ldloc.s V_6 - IL_00c6: brfalse.s IL_00f2 - IL_00c8: ldloc.s V_6 - IL_00ca: callvirt ""string System.Exception.Message.get"" - IL_00cf: stloc.s V_7 - IL_00d1: ldloc.s V_7 - IL_00d3: ldstr ""bad dog"" - IL_00d8: call ""bool string.op_Equality(string, string)"" - IL_00dd: brtrue.s IL_00ef - IL_00df: ldloc.s V_7 - IL_00e1: ldstr ""dog bad"" - IL_00e6: call ""bool string.op_Equality(string, string)"" - IL_00eb: brtrue.s IL_00ef - IL_00ed: br.s IL_00f2 - IL_00ef: ldc.i4.1 - IL_00f0: br.s IL_00f3 + IL_0094: isinst ""System.Exception"" + IL_0099: dup + IL_009a: brtrue.s IL_00a0 + IL_009c: pop + IL_009d: ldc.i4.0 + IL_009e: br.s IL_0106 + IL_00a0: stloc.s V_7 + IL_00a2: ldarg.0 + IL_00a3: ldloc.s V_7 + IL_00a5: stfld ""object C.d__1.<>s__1"" + IL_00aa: ldarg.0 + IL_00ab: ldarg.0 + IL_00ac: ldfld ""object C.d__1.<>s__1"" + IL_00b1: castclass ""System.Exception"" + IL_00b6: stfld ""System.Exception C.d__1.5__3"" + IL_00bb: ldarg.0 + IL_00bc: ldfld ""System.Exception C.d__1.5__3"" + IL_00c1: callvirt ""System.Exception System.Exception.InnerException.get"" + IL_00c6: stloc.2 + IL_00c7: ldloc.2 + IL_00c8: brfalse.s IL_00f2 + IL_00ca: ldloc.2 + IL_00cb: callvirt ""string System.Exception.Message.get"" + IL_00d0: stloc.3 + IL_00d1: ldloc.3 + IL_00d2: ldstr ""bad dog"" + IL_00d7: call ""bool string.op_Equality(string, string)"" + IL_00dc: brtrue.s IL_00ed + IL_00de: ldloc.3 + IL_00df: ldstr ""dog bad"" + IL_00e4: call ""bool string.op_Equality(string, string)"" + IL_00e9: brtrue.s IL_00ed + IL_00eb: br.s IL_00f2 + IL_00ed: ldc.i4.1 + IL_00ee: stloc.s V_4 + IL_00f0: br.s IL_00f5 IL_00f2: ldc.i4.0 - IL_00f3: stloc.s V_5 - IL_00f5: ldloc.s V_5 - IL_00f7: ldc.i4.0 - IL_00f8: cgt.un - IL_00fa: endfilter + IL_00f3: stloc.s V_4 + IL_00f5: ldarg.0 + IL_00f6: ldloc.s V_4 + IL_00f8: stfld ""bool C.d__1.<>s__4"" + IL_00fd: ldarg.0 + IL_00fe: ldfld ""bool C.d__1.<>s__4"" + IL_0103: ldc.i4.0 + IL_0104: cgt.un + IL_0106: endfilter } // end filter { // handler - IL_00fc: pop - IL_00fd: ldarg.0 - IL_00fe: ldc.i4.1 - IL_00ff: stfld ""int C.d__1.<>s__2"" - IL_0104: leave.s IL_010f + IL_0108: pop + IL_0109: ldarg.0 + IL_010a: ldc.i4.1 + IL_010b: stfld ""int C.d__1.<>s__2"" + IL_0110: leave.s IL_011b } catch object { - IL_0106: pop - IL_0107: nop - IL_0108: ldc.i4.0 - IL_0109: stloc.1 - IL_010a: leave IL_01b6 - } - IL_010f: ldarg.0 - IL_0110: ldfld ""int C.d__1.<>s__2"" - IL_0115: stloc.s V_8 - IL_0117: ldloc.s V_8 - IL_0119: ldc.i4.1 - IL_011a: beq.s IL_011e - IL_011c: br.s IL_018c - IL_011e: nop - IL_011f: call ""System.Threading.Tasks.Task C.TrueAsync()"" - IL_0124: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0129: stloc.s V_9 - IL_012b: ldloca.s V_9 - IL_012d: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_0132: brtrue.s IL_0176 - IL_0134: ldarg.0 - IL_0135: ldc.i4.1 - IL_0136: dup - IL_0137: stloc.0 - IL_0138: stfld ""int C.d__1.<>1__state"" - IL_013d: ldarg.0 - IL_013e: ldloc.s V_9 - IL_0140: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_0145: ldarg.0 - IL_0146: stloc.3 - IL_0147: ldarg.0 - IL_0148: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_014d: ldloca.s V_9 - IL_014f: ldloca.s V_3 - IL_0151: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" - IL_0156: nop - IL_0157: leave.s IL_01cb - IL_0159: ldarg.0 - IL_015a: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_015f: stloc.s V_9 - IL_0161: ldarg.0 - IL_0162: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_0167: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_016d: ldarg.0 - IL_016e: ldc.i4.m1 - IL_016f: dup - IL_0170: stloc.0 - IL_0171: stfld ""int C.d__1.<>1__state"" - IL_0176: ldarg.0 - IL_0177: ldloca.s V_9 - IL_0179: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_017e: stfld ""bool C.d__1.<>s__4"" + IL_0112: pop + IL_0113: nop + IL_0114: ldc.i4.0 + IL_0115: stloc.1 + IL_0116: leave IL_01c1 + } + IL_011b: ldarg.0 + IL_011c: ldfld ""int C.d__1.<>s__2"" + IL_0121: stloc.s V_8 + IL_0123: ldloc.s V_8 + IL_0125: ldc.i4.1 + IL_0126: beq.s IL_012a + IL_0128: br.s IL_0199 + IL_012a: nop + IL_012b: call ""System.Threading.Tasks.Task C.TrueAsync()"" + IL_0130: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" + IL_0135: stloc.s V_9 + IL_0137: ldloca.s V_9 + IL_0139: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" + IL_013e: brtrue.s IL_0183 + IL_0140: ldarg.0 + IL_0141: ldc.i4.1 + IL_0142: dup + IL_0143: stloc.0 + IL_0144: stfld ""int C.d__1.<>1__state"" + IL_0149: ldarg.0 + IL_014a: ldloc.s V_9 + IL_014c: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_0151: ldarg.0 + IL_0152: stloc.s V_6 + IL_0154: ldarg.0 + IL_0155: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_015a: ldloca.s V_9 + IL_015c: ldloca.s V_6 + IL_015e: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" + IL_0163: nop + IL_0164: leave.s IL_01d6 + IL_0166: ldarg.0 + IL_0167: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_016c: stloc.s V_9 + IL_016e: ldarg.0 + IL_016f: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_0174: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_017a: ldarg.0 + IL_017b: ldc.i4.m1 + IL_017c: dup + IL_017d: stloc.0 + IL_017e: stfld ""int C.d__1.<>1__state"" IL_0183: ldarg.0 - IL_0184: ldfld ""bool C.d__1.<>s__4"" - IL_0189: stloc.1 - IL_018a: leave.s IL_01b6 - IL_018c: ldarg.0 - IL_018d: ldnull - IL_018e: stfld ""object C.d__1.<>s__1"" - IL_0193: ldarg.0 - IL_0194: ldnull - IL_0195: stfld ""System.Exception C.d__1.5__3"" - IL_019a: leave.s IL_01b6 + IL_0184: ldloca.s V_9 + IL_0186: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_018b: stfld ""bool C.d__1.<>s__5"" + IL_0190: ldarg.0 + IL_0191: ldfld ""bool C.d__1.<>s__5"" + IL_0196: stloc.1 + IL_0197: leave.s IL_01c1 + IL_0199: ldarg.0 + IL_019a: ldnull + IL_019b: stfld ""object C.d__1.<>s__1"" + IL_01a0: ldarg.0 + IL_01a1: ldnull + IL_01a2: stfld ""System.Exception C.d__1.5__3"" + IL_01a7: leave.s IL_01c1 } catch System.Exception { - IL_019c: stloc.s V_6 - IL_019e: ldarg.0 - IL_019f: ldc.i4.s -2 - IL_01a1: stfld ""int C.d__1.<>1__state"" - IL_01a6: ldarg.0 - IL_01a7: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_01ac: ldloc.s V_6 - IL_01ae: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01b3: nop - IL_01b4: leave.s IL_01cb + IL_01a9: stloc.2 + IL_01aa: ldarg.0 + IL_01ab: ldc.i4.s -2 + IL_01ad: stfld ""int C.d__1.<>1__state"" + IL_01b2: ldarg.0 + IL_01b3: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_01b8: ldloc.2 + IL_01b9: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01be: nop + IL_01bf: leave.s IL_01d6 } - IL_01b6: ldarg.0 - IL_01b7: ldc.i4.s -2 - IL_01b9: stfld ""int C.d__1.<>1__state"" - IL_01be: ldarg.0 - IL_01bf: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_01c4: ldloc.1 - IL_01c5: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)"" - IL_01ca: nop - IL_01cb: ret + IL_01c1: ldarg.0 + IL_01c2: ldc.i4.s -2 + IL_01c4: stfld ""int C.d__1.<>1__state"" + IL_01c9: ldarg.0 + IL_01ca: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_01cf: ldloc.1 + IL_01d0: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)"" + IL_01d5: nop + IL_01d6: ret } "); } @@ -11933,8 +11940,8 @@ public static async Task ExceptionFilterBroken() comp.VerifyDiagnostics(); var verifier = CompileAndVerify(comp, expectedOutput: "True"); verifier.VerifyIL("C.d__1.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", @" -{ - // Code size 513 (0x201) + { + // Code size 527 (0x20f) .maxstack 3 .locals init (int V_0, bool V_1, @@ -11943,9 +11950,9 @@ .locals init (int V_0, System.Exception V_4, int V_5, System.Exception V_6, - bool V_7, - System.Exception V_8, - string V_9, + string V_7, + bool V_8, + System.Exception V_9, System.Runtime.CompilerServices.TaskAwaiter V_10) IL_0000: ldarg.0 IL_0001: ldfld ""int C.d__1.<>1__state"" @@ -11960,7 +11967,7 @@ .locals init (int V_0, IL_000e: beq.s IL_0014 IL_0010: br.s IL_0019 IL_0012: br.s IL_0021 - IL_0014: br IL_0184 + IL_0014: br IL_0192 IL_0019: nop IL_001a: ldarg.0 IL_001b: ldc.i4.0 @@ -11995,7 +12002,7 @@ .locals init (int V_0, IL_0058: ldloca.s V_3 IL_005a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompletedd__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" IL_005f: nop - IL_0060: leave IL_0200 + IL_0060: leave IL_020e IL_0065: ldarg.0 IL_0066: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__1"" IL_006b: stloc.2 @@ -12012,7 +12019,7 @@ .locals init (int V_0, IL_0088: nop IL_0089: ldc.i4.1 IL_008a: stloc.1 - IL_008b: leave IL_01eb + IL_008b: leave IL_01f9 } catch System.Exception { @@ -12031,7 +12038,7 @@ .locals init (int V_0, IL_00ab: ldloc.s V_5 IL_00ad: ldc.i4.1 IL_00ae: beq.s IL_00b5 - IL_00b0: br IL_01c8 + IL_00b0: br IL_01d6 IL_00b5: ldarg.0 IL_00b6: ldarg.0 IL_00b7: ldfld ""object C.d__1.<>s__1"" @@ -12054,130 +12061,135 @@ .locals init (int V_0, IL_00db: brtrue.s IL_00e1 IL_00dd: pop IL_00de: ldc.i4.0 - IL_00df: br.s IL_012e - IL_00e1: stloc.s V_6 + IL_00df: br.s IL_013c + IL_00e1: stloc.s V_9 IL_00e3: ldarg.0 - IL_00e4: ldloc.s V_6 + IL_00e4: ldloc.s V_9 IL_00e6: stfld ""object C.d__1.<>s__4"" IL_00eb: ldarg.0 IL_00ec: ldfld ""System.Exception C.d__1.5__3"" IL_00f1: callvirt ""System.Exception System.Exception.InnerException.get"" - IL_00f6: stloc.s V_8 - IL_00f8: ldloc.s V_8 - IL_00fa: brfalse.s IL_0126 - IL_00fc: ldloc.s V_8 + IL_00f6: stloc.s V_6 + IL_00f8: ldloc.s V_6 + IL_00fa: brfalse.s IL_0128 + IL_00fc: ldloc.s V_6 IL_00fe: callvirt ""string System.Exception.Message.get"" - IL_0103: stloc.s V_9 - IL_0105: ldloc.s V_9 + IL_0103: stloc.s V_7 + IL_0105: ldloc.s V_7 IL_0107: ldstr ""bad dog"" IL_010c: call ""bool string.op_Equality(string, string)"" IL_0111: brtrue.s IL_0123 - IL_0113: ldloc.s V_9 + IL_0113: ldloc.s V_7 IL_0115: ldstr ""dog bad"" IL_011a: call ""bool string.op_Equality(string, string)"" IL_011f: brtrue.s IL_0123 - IL_0121: br.s IL_0126 + IL_0121: br.s IL_0128 IL_0123: ldc.i4.1 - IL_0124: br.s IL_0127 - IL_0126: ldc.i4.0 - IL_0127: stloc.s V_7 - IL_0129: ldloc.s V_7 - IL_012b: ldc.i4.0 - IL_012c: cgt.un - IL_012e: endfilter + IL_0124: stloc.s V_8 + IL_0126: br.s IL_012b + IL_0128: ldc.i4.0 + IL_0129: stloc.s V_8 + IL_012b: ldarg.0 + IL_012c: ldloc.s V_8 + IL_012e: stfld ""bool C.d__1.<>s__6"" + IL_0133: ldarg.0 + IL_0134: ldfld ""bool C.d__1.<>s__6"" + IL_0139: ldc.i4.0 + IL_013a: cgt.un + IL_013c: endfilter } // end filter { // handler - IL_0130: pop - IL_0131: ldarg.0 - IL_0132: ldc.i4.1 - IL_0133: stfld ""int C.d__1.<>s__5"" - IL_0138: leave.s IL_013a - } - IL_013a: ldarg.0 - IL_013b: ldfld ""int C.d__1.<>s__5"" - IL_0140: stloc.s V_5 - IL_0142: ldloc.s V_5 - IL_0144: ldc.i4.1 - IL_0145: beq.s IL_0149 - IL_0147: br.s IL_01b7 - IL_0149: nop - IL_014a: call ""System.Threading.Tasks.Task C.TrueAsync()"" - IL_014f: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" - IL_0154: stloc.s V_10 - IL_0156: ldloca.s V_10 - IL_0158: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" - IL_015d: brtrue.s IL_01a1 - IL_015f: ldarg.0 - IL_0160: ldc.i4.1 - IL_0161: dup - IL_0162: stloc.0 - IL_0163: stfld ""int C.d__1.<>1__state"" - IL_0168: ldarg.0 - IL_0169: ldloc.s V_10 - IL_016b: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_0170: ldarg.0 - IL_0171: stloc.3 - IL_0172: ldarg.0 - IL_0173: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_0178: ldloca.s V_10 - IL_017a: ldloca.s V_3 - IL_017c: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" - IL_0181: nop - IL_0182: leave.s IL_0200 - IL_0184: ldarg.0 - IL_0185: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_018a: stloc.s V_10 - IL_018c: ldarg.0 - IL_018d: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" - IL_0192: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" - IL_0198: ldarg.0 - IL_0199: ldc.i4.m1 - IL_019a: dup - IL_019b: stloc.0 - IL_019c: stfld ""int C.d__1.<>1__state"" - IL_01a1: ldarg.0 - IL_01a2: ldloca.s V_10 - IL_01a4: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" - IL_01a9: stfld ""bool C.d__1.<>s__6"" - IL_01ae: ldarg.0 - IL_01af: ldfld ""bool C.d__1.<>s__6"" - IL_01b4: stloc.1 - IL_01b5: leave.s IL_01eb - IL_01b7: ldarg.0 - IL_01b8: ldnull - IL_01b9: stfld ""object C.d__1.<>s__4"" - IL_01be: nop - IL_01bf: ldarg.0 - IL_01c0: ldnull - IL_01c1: stfld ""System.Exception C.d__1.5__3"" - IL_01c6: br.s IL_01c8 - IL_01c8: ldarg.0 - IL_01c9: ldnull - IL_01ca: stfld ""object C.d__1.<>s__1"" - IL_01cf: leave.s IL_01eb + IL_013e: pop + IL_013f: ldarg.0 + IL_0140: ldc.i4.1 + IL_0141: stfld ""int C.d__1.<>s__5"" + IL_0146: leave.s IL_0148 + } + IL_0148: ldarg.0 + IL_0149: ldfld ""int C.d__1.<>s__5"" + IL_014e: stloc.s V_5 + IL_0150: ldloc.s V_5 + IL_0152: ldc.i4.1 + IL_0153: beq.s IL_0157 + IL_0155: br.s IL_01c5 + IL_0157: nop + IL_0158: call ""System.Threading.Tasks.Task C.TrueAsync()"" + IL_015d: callvirt ""System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()"" + IL_0162: stloc.s V_10 + IL_0164: ldloca.s V_10 + IL_0166: call ""bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get"" + IL_016b: brtrue.s IL_01af + IL_016d: ldarg.0 + IL_016e: ldc.i4.1 + IL_016f: dup + IL_0170: stloc.0 + IL_0171: stfld ""int C.d__1.<>1__state"" + IL_0176: ldarg.0 + IL_0177: ldloc.s V_10 + IL_0179: stfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_017e: ldarg.0 + IL_017f: stloc.3 + IL_0180: ldarg.0 + IL_0181: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0186: ldloca.s V_10 + IL_0188: ldloca.s V_3 + IL_018a: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, C.d__1>(ref System.Runtime.CompilerServices.TaskAwaiter, ref C.d__1)"" + IL_018f: nop + IL_0190: leave.s IL_020e + IL_0192: ldarg.0 + IL_0193: ldfld ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_0198: stloc.s V_10 + IL_019a: ldarg.0 + IL_019b: ldflda ""System.Runtime.CompilerServices.TaskAwaiter C.d__1.<>u__2"" + IL_01a0: initobj ""System.Runtime.CompilerServices.TaskAwaiter"" + IL_01a6: ldarg.0 + IL_01a7: ldc.i4.m1 + IL_01a8: dup + IL_01a9: stloc.0 + IL_01aa: stfld ""int C.d__1.<>1__state"" + IL_01af: ldarg.0 + IL_01b0: ldloca.s V_10 + IL_01b2: call ""bool System.Runtime.CompilerServices.TaskAwaiter.GetResult()"" + IL_01b7: stfld ""bool C.d__1.<>s__7"" + IL_01bc: ldarg.0 + IL_01bd: ldfld ""bool C.d__1.<>s__7"" + IL_01c2: stloc.1 + IL_01c3: leave.s IL_01f9 + IL_01c5: ldarg.0 + IL_01c6: ldnull + IL_01c7: stfld ""object C.d__1.<>s__4"" + IL_01cc: nop + IL_01cd: ldarg.0 + IL_01ce: ldnull + IL_01cf: stfld ""System.Exception C.d__1.5__3"" + IL_01d4: br.s IL_01d6 + IL_01d6: ldarg.0 + IL_01d7: ldnull + IL_01d8: stfld ""object C.d__1.<>s__1"" + IL_01dd: leave.s IL_01f9 } catch System.Exception { - IL_01d1: stloc.s V_8 - IL_01d3: ldarg.0 - IL_01d4: ldc.i4.s -2 - IL_01d6: stfld ""int C.d__1.<>1__state"" - IL_01db: ldarg.0 - IL_01dc: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_01e1: ldloc.s V_8 - IL_01e3: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" - IL_01e8: nop - IL_01e9: leave.s IL_0200 + IL_01df: stloc.s V_6 + IL_01e1: ldarg.0 + IL_01e2: ldc.i4.s -2 + IL_01e4: stfld ""int C.d__1.<>1__state"" + IL_01e9: ldarg.0 + IL_01ea: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_01ef: ldloc.s V_6 + IL_01f1: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)"" + IL_01f6: nop + IL_01f7: leave.s IL_020e } - IL_01eb: ldarg.0 - IL_01ec: ldc.i4.s -2 - IL_01ee: stfld ""int C.d__1.<>1__state"" - IL_01f3: ldarg.0 - IL_01f4: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" - IL_01f9: ldloc.1 - IL_01fa: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)"" - IL_01ff: nop - IL_0200: ret + IL_01f9: ldarg.0 + IL_01fa: ldc.i4.s -2 + IL_01fc: stfld ""int C.d__1.<>1__state"" + IL_0201: ldarg.0 + IL_0202: ldflda ""System.Runtime.CompilerServices.AsyncTaskMethodBuilder C.d__1.<>t__builder"" + IL_0207: ldloc.1 + IL_0208: call ""void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)"" + IL_020d: nop + IL_020e: ret } "); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests3.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests3.cs index 1be33c211fbeb..27bd784d69384 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests3.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests3.cs @@ -6420,60 +6420,25 @@ class C {{ static void Main() {{ - M1(41); - M1(42); - M1(43); - WriteLine(M2(41)); - WriteLine(M2(42)); - WriteLine(M2(43)); + object o = 42; + M(o); }} - static void M1(object o) + static void M(object o) {{ if ({pattern}) return; WriteLine(o); }} - static bool M2(object o) - {{ - return ({pattern}); - }} }}"; - string expectedOutput = """ -41 -42 -False -False -True -"""; - var verifier = CompileAndVerify(source, expectedOutput: expectedOutput); - verifier.VerifyIL("C.M1", -@"{ - // Code size 30 (0x1e) - .maxstack 2 - .locals init (int V_0) - IL_0000: ldarg.0 - IL_0001: isinst ""int"" - IL_0006: brfalse.s IL_0016 - IL_0008: ldarg.0 - IL_0009: unbox.any ""int"" - IL_000e: stloc.0 - IL_000f: ldloc.0 - IL_0010: ldc.i4.s 41 - IL_0012: sub - IL_0013: ldc.i4.1 - IL_0014: ble.un.s IL_0017 - IL_0016: ret - IL_0017: ldarg.0 - IL_0018: call ""void System.Console.WriteLine(object)"" - IL_001d: ret -}"); - verifier.VerifyIL("C.M2", + var verifier = CompileAndVerify(source, expectedOutput: "42"); + verifier.VerifyIL("C.M", @"{ - // Code size 26 (0x1a) + // Code size 39 (0x27) .maxstack 2 - .locals init (int V_0) + .locals init (int V_0, + bool V_1) IL_0000: ldarg.0 IL_0001: isinst ""int"" - IL_0006: brfalse.s IL_0018 + IL_0006: brfalse.s IL_001a IL_0008: ldarg.0 IL_0009: unbox.any ""int"" IL_000e: stloc.0 @@ -6481,11 +6446,18 @@ .locals init (int V_0) IL_0010: ldc.i4.s 41 IL_0012: sub IL_0013: ldc.i4.1 - IL_0014: bgt.un.s IL_0018 - IL_0016: ldc.i4.0 - IL_0017: ret - IL_0018: ldc.i4.1 - IL_0019: ret + IL_0014: bgt.un.s IL_001a + IL_0016: ldc.i4.1 + IL_0017: stloc.1 + IL_0018: br.s IL_001c + IL_001a: ldc.i4.0 + IL_001b: stloc.1 + IL_001c: ldloc.1 + IL_001d: brtrue.s IL_0020 + IL_001f: ret + IL_0020: ldarg.0 + IL_0021: call ""void System.Console.WriteLine(object)"" + IL_0026: ret }"); } diff --git a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests5.cs b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests5.cs index cd99ca9ea6484..0120dc6e33d29 100644 --- a/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests5.cs +++ b/src/Compilers/CSharp/Test/Emit2/Semantics/PatternMatchingTests5.cs @@ -3178,17 +3178,21 @@ public static bool Test(int a) var compilation = CompileAndVerify(source, expectedOutput: "True"); compilation.VerifyIL("C.Test", """ { - // Code size 10 (0xa) + // Code size 14 (0xe) .maxstack 2 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: sub IL_0003: ldc.i4.7 - IL_0004: bgt.un.s IL_0008 + IL_0004: bgt.un.s IL_000a IL_0006: ldc.i4.1 - IL_0007: ret - IL_0008: ldc.i4.0 - IL_0009: ret + IL_0007: stloc.0 + IL_0008: br.s IL_000c + IL_000a: ldc.i4.0 + IL_000b: stloc.0 + IL_000c: ldloc.0 + IL_000d: ret } """); } @@ -3223,8 +3227,9 @@ public static bool Test(int a, object b) var compilation = CompileAndVerify(source, expectedOutput: "True"); compilation.VerifyIL("C.Test", """ { - // Code size 68 (0x44) + // Code size 72 (0x48) .maxstack 2 + .locals init (bool V_0) IL_0000: ldarg.0 IL_0001: ldc.i4.1 IL_0002: sub @@ -3233,26 +3238,29 @@ .maxstack 2 IL_0024, IL_002e, IL_0038) - IL_0018: br.s IL_0042 + IL_0018: br.s IL_0044 IL_001a: ldarg.1 IL_001b: isinst "int" IL_0020: brtrue.s IL_0040 - IL_0022: br.s IL_0042 + IL_0022: br.s IL_0044 IL_0024: ldarg.1 IL_0025: isinst "bool" IL_002a: brtrue.s IL_0040 - IL_002c: br.s IL_0042 + IL_002c: br.s IL_0044 IL_002e: ldarg.1 IL_002f: isinst "double" IL_0034: brtrue.s IL_0040 - IL_0036: br.s IL_0042 + IL_0036: br.s IL_0044 IL_0038: ldarg.1 IL_0039: isinst "long" - IL_003e: brfalse.s IL_0042 + IL_003e: brfalse.s IL_0044 IL_0040: ldc.i4.1 - IL_0041: ret - IL_0042: ldc.i4.0 - IL_0043: ret + IL_0041: stloc.0 + IL_0042: br.s IL_0046 + IL_0044: ldc.i4.0 + IL_0045: stloc.0 + IL_0046: ldloc.0 + IL_0047: ret } """); } @@ -3286,23 +3294,24 @@ public static bool Test(string a) var compilation = CompileAndVerify(source, expectedOutput: "True"); compilation.VerifyIL("C.Test", """ { - // Code size 69 (0x45) + // Code size 73 (0x49) .maxstack 2 - .locals init (int V_0, - char V_1) + .locals init (bool V_0, + int V_1, + char V_2) IL_0000: ldarg.0 - IL_0001: brfalse.s IL_0043 + IL_0001: brfalse.s IL_0045 IL_0003: ldarg.0 IL_0004: call "int string.Length.get" - IL_0009: stloc.0 - IL_000a: ldloc.0 + IL_0009: stloc.1 + IL_000a: ldloc.1 IL_000b: ldc.i4.1 - IL_000c: bne.un.s IL_0043 + IL_000c: bne.un.s IL_0045 IL_000e: ldarg.0 IL_000f: ldc.i4.0 IL_0010: call "char string.this[int].get" - IL_0015: stloc.1 - IL_0016: ldloc.1 + IL_0015: stloc.2 + IL_0016: ldloc.2 IL_0017: ldc.i4.s 49 IL_0019: sub IL_001a: switch ( @@ -3314,11 +3323,14 @@ .locals init (int V_0, IL_0041, IL_0041, IL_0041) - IL_003f: br.s IL_0043 + IL_003f: br.s IL_0045 IL_0041: ldc.i4.1 - IL_0042: ret - IL_0043: ldc.i4.0 - IL_0044: ret + IL_0042: stloc.0 + IL_0043: br.s IL_0047 + IL_0045: ldc.i4.0 + IL_0046: stloc.0 + IL_0047: ldloc.0 + IL_0048: ret } """); } @@ -3344,138 +3356,5 @@ bool M0({type} x0) Diagnostic(ErrorCode.ERR_ConstantExpected, expression).WithLocation(6, 22) ); } - - [Fact] - public void IsPatternExpressionWithAwait() - { - var source = """ -using System; -using System.Threading.Tasks; - -Console.WriteLine(await Async1(30)); -Console.WriteLine(await Async1(40)); -Console.WriteLine(await Async1(50)); - -Console.WriteLine(await Async2(30)); -Console.WriteLine(await Async2(40)); -Console.WriteLine(await Async2(50)); - -Console.WriteLine(await Async3(30)); -Console.WriteLine(await Async3(40)); -Console.WriteLine(await Async3(50)); - -static async Task Async1(int i) { - // sub-expression - return await Task.FromResult(false) || i is 30 or 40; -} -static async Task Async2(int i) { - // input-expression - return await Task.FromResult(i) is 30 or 40; -} -static async Task Async3(int i) { - // expression-list - return (await Task.FromResult(0), i is 30 or 40).Item2; -} -"""; - var expectedOutput = """ -True -True -False -True -True -False -True -True -False -"""; - var verifier = CompileAndVerify(source, expectedOutput: expectedOutput); - // await in input-expression - verifier.VerifyIL("Program.<<
$>g__Async2|0_1>d.System.Runtime.CompilerServices.IAsyncStateMachine.MoveNext()", """ -{ - // Code size 167 (0xa7) - .maxstack 3 - .locals init (int V_0, - bool V_1, - int V_2, - System.Runtime.CompilerServices.TaskAwaiter V_3, - System.Exception V_4) - IL_0000: ldarg.0 - IL_0001: ldfld "int Program.<<
$>g__Async2|0_1>d.<>1__state" - IL_0006: stloc.0 - .try - { - IL_0007: ldloc.0 - IL_0008: brfalse.s IL_0044 - IL_000a: ldarg.0 - IL_000b: ldfld "int Program.<<
$>g__Async2|0_1>d.i" - IL_0010: call "System.Threading.Tasks.Task System.Threading.Tasks.Task.FromResult(int)" - IL_0015: callvirt "System.Runtime.CompilerServices.TaskAwaiter System.Threading.Tasks.Task.GetAwaiter()" - IL_001a: stloc.3 - IL_001b: ldloca.s V_3 - IL_001d: call "bool System.Runtime.CompilerServices.TaskAwaiter.IsCompleted.get" - IL_0022: brtrue.s IL_0060 - IL_0024: ldarg.0 - IL_0025: ldc.i4.0 - IL_0026: dup - IL_0027: stloc.0 - IL_0028: stfld "int Program.<<
$>g__Async2|0_1>d.<>1__state" - IL_002d: ldarg.0 - IL_002e: ldloc.3 - IL_002f: stfld "System.Runtime.CompilerServices.TaskAwaiter Program.<<
$>g__Async2|0_1>d.<>u__1" - IL_0034: ldarg.0 - IL_0035: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__Async2|0_1>d.<>t__builder" - IL_003a: ldloca.s V_3 - IL_003c: ldarg.0 - IL_003d: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.AwaitUnsafeOnCompleted, Program.<<
$>g__Async2|0_1>d>(ref System.Runtime.CompilerServices.TaskAwaiter, ref Program.<<
$>g__Async2|0_1>d)" - IL_0042: leave.s IL_00a6 - IL_0044: ldarg.0 - IL_0045: ldfld "System.Runtime.CompilerServices.TaskAwaiter Program.<<
$>g__Async2|0_1>d.<>u__1" - IL_004a: stloc.3 - IL_004b: ldarg.0 - IL_004c: ldflda "System.Runtime.CompilerServices.TaskAwaiter Program.<<
$>g__Async2|0_1>d.<>u__1" - IL_0051: initobj "System.Runtime.CompilerServices.TaskAwaiter" - IL_0057: ldarg.0 - IL_0058: ldc.i4.m1 - IL_0059: dup - IL_005a: stloc.0 - IL_005b: stfld "int Program.<<
$>g__Async2|0_1>d.<>1__state" - IL_0060: ldloca.s V_3 - IL_0062: call "int System.Runtime.CompilerServices.TaskAwaiter.GetResult()" - IL_0067: stloc.2 - IL_0068: ldloc.2 - IL_0069: ldc.i4.s 30 - IL_006b: beq.s IL_0072 - IL_006d: ldloc.2 - IL_006e: ldc.i4.s 40 - IL_0070: bne.un.s IL_0075 - IL_0072: ldc.i4.1 - IL_0073: br.s IL_0076 - IL_0075: ldc.i4.0 - IL_0076: stloc.1 - IL_0077: leave.s IL_0092 - } - catch System.Exception - { - IL_0079: stloc.s V_4 - IL_007b: ldarg.0 - IL_007c: ldc.i4.s -2 - IL_007e: stfld "int Program.<<
$>g__Async2|0_1>d.<>1__state" - IL_0083: ldarg.0 - IL_0084: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__Async2|0_1>d.<>t__builder" - IL_0089: ldloc.s V_4 - IL_008b: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetException(System.Exception)" - IL_0090: leave.s IL_00a6 - } - IL_0092: ldarg.0 - IL_0093: ldc.i4.s -2 - IL_0095: stfld "int Program.<<
$>g__Async2|0_1>d.<>1__state" - IL_009a: ldarg.0 - IL_009b: ldflda "System.Runtime.CompilerServices.AsyncTaskMethodBuilder Program.<<
$>g__Async2|0_1>d.<>t__builder" - IL_00a0: ldloc.1 - IL_00a1: call "void System.Runtime.CompilerServices.AsyncTaskMethodBuilder.SetResult(bool)" - IL_00a6: ret -} -"""); - } } } diff --git a/src/Compilers/Core/Portable/CodeGen/ILBuilder.cs b/src/Compilers/Core/Portable/CodeGen/ILBuilder.cs index 982678a561575..31c1053d5c5e9 100644 --- a/src/Compilers/Core/Portable/CodeGen/ILBuilder.cs +++ b/src/Compilers/Core/Portable/CodeGen/ILBuilder.cs @@ -1083,16 +1083,6 @@ internal void AssertStackEmpty() Debug.Assert(_emitState.CurStack == 0); } - [Conditional("DEBUG")] - internal void AssertStackDepth(int stack) - { - Debug.Assert(_emitState.CurStack == stack); - } - -#if DEBUG - internal int GetStackDepth() => _emitState.CurStack; -#endif - // true if there may have been a label generated with no subsequent code internal bool IsJustPastLabel() {