diff --git a/src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs b/src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
index 4496196c67e24..3fb0dbc980ae0 100644
--- a/src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
+++ b/src/Compilers/CSharp/Portable/Binder/SubsumptionDiagnosticBuilder.cs
@@ -2,11 +2,11 @@
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
{
-
///
/// Helper class for binding the pattern switch statement. It helps compute which labels
/// are subsumed and/or reachable. The strategy, implemented in ,
@@ -15,12 +15,12 @@ namespace Microsoft.CodeAnalysis.CSharp
/// If it is not subsumed and there is no guard expression, we then add it to the decision
/// tree.
///
- internal class SubsumptionDiagnosticBuilder : DecisionTreeBuilder
+ internal sealed class SubsumptionDiagnosticBuilder : DecisionTreeBuilder
{
private readonly DecisionTree _subsumptionTree;
internal SubsumptionDiagnosticBuilder(Symbol enclosingSymbol,
- SyntaxNode syntax,
+ SwitchStatementSyntax syntax,
Conversions conversions,
BoundExpression expression)
: base(enclosingSymbol, syntax, conversions)
@@ -52,7 +52,6 @@ internal bool AddLabel(BoundPatternSwitchLabel label, DiagnosticBag diagnostics,
{
// For purposes of subsumption, we do not take into consideration the value
// of the input expression. Therefore we consider null possible if the type permits.
- Syntax = label.Syntax;
var inputCouldBeNull = _subsumptionTree.Type.CanContainNull();
var subsumedErrorCode = CheckSubsumed(label.Pattern, _subsumptionTree, inputCouldBeNull: inputCouldBeNull);
if (subsumedErrorCode != 0 && subsumedErrorCode != ErrorCode.ERR_NoImplicitConvCast)
diff --git a/src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs b/src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
index 703dffcf48a03..cf099b336a8a7 100644
--- a/src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
+++ b/src/Compilers/CSharp/Portable/BoundTree/DecisionTreeBuilder.cs
@@ -4,6 +4,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using System.Linq;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.CSharp.Symbols;
using Roslyn.Utilities;
@@ -26,30 +27,32 @@ internal abstract class DecisionTreeBuilder
protected readonly Symbol _enclosingSymbol;
protected readonly Conversions _conversions;
protected HashSet _useSiteDiagnostics = new HashSet();
+ protected readonly SwitchStatementSyntax _switchSyntax;
private Dictionary localByType = new Dictionary();
protected DecisionTreeBuilder(
Symbol enclosingSymbol,
- SyntaxNode syntax,
+ SwitchStatementSyntax switchSyntax,
Conversions conversions)
{
- this._enclosingSymbol = enclosingSymbol;
- this.Syntax = syntax;
- this._conversions = conversions;
+ _enclosingSymbol = enclosingSymbol;
+ _switchSyntax = switchSyntax;
+ _conversions = conversions;
}
- protected SyntaxNode Syntax { private get; set; }
-
- private LocalSymbol PatternMatchingTemp(TypeSymbol type)
+ private BoundLocal GetBoundPatternMatchingLocal(TypeSymbol type)
{
- LocalSymbol temp;
- if (!localByType.TryGetValue(type, out temp))
+ // All synthesized pattern matching locals are associated with the Switch statement syntax node.
+ // Their ordinals are zero.
+ // EnC local slot variable matching logic find the right slot based on the type of the local.
+
+ if (!localByType.TryGetValue(type, out var localSymbol))
{
- temp = new SynthesizedLocal(_enclosingSymbol as MethodSymbol, type, SynthesizedLocalKind.PatternMatching, Syntax);
- localByType.Add(type, temp);
+ localSymbol = new SynthesizedLocal(_enclosingSymbol as MethodSymbol, type, SynthesizedLocalKind.SwitchCasePatternMatching, _switchSyntax);
+ localByType.Add(type, localSymbol);
}
- return temp;
+ return new BoundLocal(_switchSyntax, localSymbol, null, type);
}
///
@@ -59,13 +62,14 @@ protected DecisionTree CreateEmptyDecisionTree(BoundExpression expression)
{
var type = expression.Type;
- LocalSymbol temp = null;
+ LocalSymbol localSymbol = null;
if (expression.ConstantValue == null)
{
// Unless it is a constant, the decision tree acts on a copy of the input expression.
// We create a temp to represent that copy. Lowering will assign into this temp.
- temp = PatternMatchingTemp(type);
- expression = new BoundLocal(expression.Syntax, temp, null, type);
+ var local = GetBoundPatternMatchingLocal(type);
+ expression = local;
+ localSymbol = local.LocalSymbol;
}
if (type.CanContainNull() || type.SpecialType == SpecialType.None)
@@ -74,12 +78,12 @@ protected DecisionTree CreateEmptyDecisionTree(BoundExpression expression)
// Note that, for the purpose of the decision tree (and subsumption), we
// ignore the fact that the input may be a constant, and therefore always
// or never null.
- return new DecisionTree.ByType(expression, type, temp);
+ return new DecisionTree.ByType(expression, type, localSymbol);
}
else
{
// If it is a (e.g. builtin) value type, we can switch on its (constant) values.
- return new DecisionTree.ByValue(expression, type, temp);
+ return new DecisionTree.ByValue(expression, type, localSymbol);
}
}
@@ -283,10 +287,9 @@ private DecisionTree AddByValue(DecisionTree.ByType byType, BoundConstantPattern
if (forType == null)
{
var type = value.Value.Type;
- var localSymbol = PatternMatchingTemp(type);
- var narrowedExpression = new BoundLocal(Syntax, localSymbol, null, type);
- forType = new DecisionTree.ByValue(narrowedExpression, value.Value.Type.TupleUnderlyingTypeOrSelf(), localSymbol);
- byType.TypeAndDecision.Add(new KeyValuePair(value.Value.Type, forType));
+ var narrowedExpression = GetBoundPatternMatchingLocal(type);
+ forType = new DecisionTree.ByValue(narrowedExpression, type.TupleUnderlyingTypeOrSelf(), narrowedExpression.LocalSymbol);
+ byType.TypeAndDecision.Add(new KeyValuePair(type, forType));
}
return AddByValue(forType, value, makeDecision);
@@ -384,11 +387,10 @@ private DecisionTree AddByType(DecisionTree.ByType byType, TypeSymbol type, Deci
if (result == null)
{
- var localSymbol = PatternMatchingTemp(type);
- var expression = new BoundLocal(Syntax, localSymbol, null, type);
+ var expression = GetBoundPatternMatchingLocal(type);
result = makeDecision(expression, type);
Debug.Assert(result.Temp == null);
- result.Temp = localSymbol;
+ result.Temp = expression.LocalSymbol;
byType.TypeAndDecision.Add(new KeyValuePair(type, result));
}
diff --git a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
index f40172c021fbe..392d6040b973d 100644
--- a/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
+++ b/src/Compilers/CSharp/Portable/CodeGen/EmitStatement.cs
@@ -1535,7 +1535,11 @@ private string GetLocalDebugName(ILocalSymbolInternal local, out LocalDebugId lo
var syntax = local.GetDeclaratorSyntax();
int syntaxOffset = _method.CalculateLocalSyntaxOffset(syntax.SpanStart, syntax.SyntaxTree);
- int ordinal = _synthesizedLocalOrdinals.AssignLocalOrdinal(localKind, syntaxOffset);
+ // Synthesized locals emitted for switch case patterns are all associated with the switch statement
+ // and have distinct types. We use theier types to match them, not the ordinal as the ordinal might
+ // change if switch cases are reordered.
+ int ordinal = (localKind != SynthesizedLocalKind.SwitchCasePatternMatching) ?
+ _synthesizedLocalOrdinals.AssignLocalOrdinal(localKind, syntaxOffset) : 0;
// user-defined locals should have 0 ordinal:
Debug.Assert(ordinal == 0 || localKind != SynthesizedLocalKind.UserDefined);
diff --git a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
index c8f353222bbab..1eede24c39954 100644
--- a/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
+++ b/src/Compilers/CSharp/Portable/Lowering/LocalRewriter/LocalRewriter_PatternSwitchStatement.cs
@@ -5,6 +5,7 @@
using System.Collections.Immutable;
using System.Diagnostics;
using Microsoft.CodeAnalysis.CSharp.Symbols;
+using Microsoft.CodeAnalysis.CSharp.Syntax;
using Roslyn.Utilities;
namespace Microsoft.CodeAnalysis.CSharp
@@ -38,14 +39,14 @@ private class PatternSwitchLocalRewriter : DecisionTreeBuilder
private ArrayBuilder _loweredDecisionTree = ArrayBuilder.GetInstance();
private PatternSwitchLocalRewriter(LocalRewriter localRewriter, BoundPatternSwitchStatement node)
- : base(localRewriter._factory.CurrentMethod, node.Syntax, localRewriter._factory.Compilation.Conversions)
+ : base(localRewriter._factory.CurrentMethod, (SwitchStatementSyntax)node.Syntax, localRewriter._factory.Compilation.Conversions)
{
this._localRewriter = localRewriter;
this._factory = localRewriter._factory;
this._factory.Syntax = node.Syntax;
foreach (var section in node.SwitchSections)
{
- _switchSections.Add((SyntaxNode)section.Syntax, ArrayBuilder.GetInstance());
+ _switchSections.Add(section.Syntax, ArrayBuilder.GetInstance());
}
}
@@ -146,7 +147,7 @@ private DecisionTree LowerToDecisionTree(
SyntaxNode defaultSection = null;
foreach (var section in node.SwitchSections)
{
- var sectionSyntax = (SyntaxNode)section.Syntax;
+ var sectionSyntax = section.Syntax;
foreach (var label in section.SwitchLabels)
{
var loweredLabel = LowerSwitchLabel(label);
@@ -164,7 +165,6 @@ private DecisionTree LowerToDecisionTree(
}
else
{
- Syntax = label.Syntax;
AddToDecisionTree(loweredDecisionTree, sectionSyntax, loweredLabel);
}
}
diff --git a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
index 3472ef5b26ed6..148ef28e9aaaa 100644
--- a/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/CodeGen/SwitchTests.cs
@@ -9433,7 +9433,7 @@ .locals init (object V_0,
-
+
diff --git a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
index 2ceeac1661b2f..3ace3ef622237 100644
--- a/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/Emit/EditAndContinue/LocalSlotMappingTests.cs
@@ -9,6 +9,7 @@
using Microsoft.CodeAnalysis.CSharp.UnitTests;
using Microsoft.CodeAnalysis.Emit;
using Microsoft.CodeAnalysis.Test.Utilities;
+using Microsoft.DiaSymReader.Tools;
using Roslyn.Test.Utilities;
using Roslyn.Utilities;
using Xunit;
@@ -2350,6 +2351,298 @@ .locals init (int V_0)
}");
}
+ [Fact]
+ public void Switch_Patterns()
+ {
+ var source = @"
+using static System.Console;
+class C
+{
+ static object F() => 1;
+ static bool P() => false;
+
+ static void M()
+ {
+ switch (F())
+ {
+ case 1: WriteLine(""int 1""); break;
+ case byte b when P(): WriteLine(b); break;
+ case int i when P(): WriteLine(i); break;
+ case (byte)1: WriteLine(""byte 1""); break;
+ case int j: WriteLine(j); break;
+ case object o: WriteLine(o); break;
+ }
+ }
+}";
+ var compilation0 = CreateStandardCompilation(source, options: TestOptions.DebugDll);
+ var compilation1 = compilation0.WithSource(source);
+
+ var v0 = CompileAndVerify(compilation0);
+
+ v0.VerifyPdb("C.M", @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+", options: PdbToXmlOptions.ExcludeScopes | PdbToXmlOptions.ExcludeSequencePoints);
+
+ v0.VerifyIL("C.M", @"
+{
+ // Code size 235 (0xeb)
+ .maxstack 2
+ .locals init (object V_0,
+ int V_1,
+ byte V_2,
+ byte V_3, //b
+ int V_4, //i
+ int V_5, //j
+ object V_6, //o
+ object V_7,
+ int? V_8,
+ byte? V_9)
+ IL_0000: nop
+ IL_0001: call ""object C.F()""
+ IL_0006: stloc.s V_7
+ IL_0008: ldloc.s V_7
+ IL_000a: stloc.0
+ IL_000b: ldloc.0
+ IL_000c: brtrue.s IL_0010
+ IL_000e: br.s IL_0086
+ IL_0010: ldloc.0
+ IL_0011: isinst ""int?""
+ IL_0016: unbox.any ""int?""
+ IL_001b: stloc.s V_8
+ IL_001d: ldloca.s V_8
+ IL_001f: call ""int int?.GetValueOrDefault()""
+ IL_0024: stloc.1
+ IL_0025: ldloca.s V_8
+ IL_0027: call ""bool int?.HasValue.get""
+ IL_002c: brfalse.s IL_0036
+ IL_002e: ldloc.1
+ IL_002f: ldc.i4.1
+ IL_0030: beq.s IL_0034
+ IL_0032: br.s IL_0036
+ IL_0034: br.s IL_0088
+ IL_0036: ldloc.0
+ IL_0037: isinst ""byte?""
+ IL_003c: unbox.any ""byte?""
+ IL_0041: stloc.s V_9
+ IL_0043: ldloca.s V_9
+ IL_0045: call ""byte byte?.GetValueOrDefault()""
+ IL_004a: stloc.2
+ IL_004b: ldloca.s V_9
+ IL_004d: call ""bool byte?.HasValue.get""
+ IL_0052: brfalse.s IL_0060
+ IL_0054: br.s IL_0095
+ IL_0056: ldloc.2
+ IL_0057: stloc.2
+ IL_0058: ldloc.2
+ IL_0059: ldc.i4.1
+ IL_005a: beq.s IL_005e
+ IL_005c: br.s IL_0060
+ IL_005e: br.s IL_00bf
+ IL_0060: ldloc.0
+ IL_0061: isinst ""int?""
+ IL_0066: unbox.any ""int?""
+ IL_006b: stloc.s V_8
+ IL_006d: ldloca.s V_8
+ IL_006f: call ""int int?.GetValueOrDefault()""
+ IL_0074: stloc.1
+ IL_0075: ldloca.s V_8
+ IL_0077: call ""bool int?.HasValue.get""
+ IL_007c: brfalse.s IL_0082
+ IL_007e: br.s IL_00a9
+ IL_0080: br.s IL_00cc
+ IL_0082: ldloc.0
+ IL_0083: stloc.0
+ IL_0084: br.s IL_00db
+ IL_0086: br.s IL_00ea
+ IL_0088: ldstr ""int 1""
+ IL_008d: call ""void System.Console.WriteLine(string)""
+ IL_0092: nop
+ IL_0093: br.s IL_00ea
+ IL_0095: ldloc.2
+ IL_0096: stloc.3
+ IL_0097: call ""bool C.P()""
+ IL_009c: brtrue.s IL_00a0
+ IL_009e: br.s IL_0056
+ IL_00a0: ldloc.3
+ IL_00a1: call ""void System.Console.WriteLine(int)""
+ IL_00a6: nop
+ IL_00a7: br.s IL_00ea
+ IL_00a9: ldloc.1
+ IL_00aa: stloc.s V_4
+ IL_00ac: call ""bool C.P()""
+ IL_00b1: brtrue.s IL_00b5
+ IL_00b3: br.s IL_0080
+ IL_00b5: ldloc.s V_4
+ IL_00b7: call ""void System.Console.WriteLine(int)""
+ IL_00bc: nop
+ IL_00bd: br.s IL_00ea
+ IL_00bf: ldstr ""byte 1""
+ IL_00c4: call ""void System.Console.WriteLine(string)""
+ IL_00c9: nop
+ IL_00ca: br.s IL_00ea
+ IL_00cc: ldloc.1
+ IL_00cd: stloc.s V_5
+ IL_00cf: br.s IL_00d1
+ IL_00d1: ldloc.s V_5
+ IL_00d3: call ""void System.Console.WriteLine(int)""
+ IL_00d8: nop
+ IL_00d9: br.s IL_00ea
+ IL_00db: ldloc.0
+ IL_00dc: stloc.s V_6
+ IL_00de: br.s IL_00e0
+ IL_00e0: ldloc.s V_6
+ IL_00e2: call ""void System.Console.WriteLine(object)""
+ IL_00e7: nop
+ IL_00e8: br.s IL_00ea
+ IL_00ea: ret
+}");
+
+ var methodData0 = v0.TestData.GetMethodData("C.M");
+ var method0 = compilation0.GetMember("C.M");
+ var method1 = compilation1.GetMember("C.M");
+ var generation0 = EmitBaseline.CreateInitialBaseline(ModuleMetadata.CreateFromImage(v0.EmittedAssemblyData), methodData0.EncDebugInfoProvider());
+
+ var diff1 = compilation1.EmitDifference(
+ generation0,
+ ImmutableArray.Create(new SemanticEdit(SemanticEditKind.Update, method0, method1, GetEquivalentNodesMap(method1, method0), preserveLocalVariables: true)));
+
+ diff1.VerifyIL("C.M", @"
+{
+ // Code size 235 (0xeb)
+ .maxstack 2
+ .locals init (object V_0,
+ int V_1,
+ byte V_2,
+ byte V_3, //b
+ int V_4, //i
+ int V_5, //j
+ object V_6, //o
+ object V_7,
+ [unchanged] V_8,
+ [unchanged] V_9,
+ int? V_10,
+ byte? V_11)
+ IL_0000: nop
+ IL_0001: call ""object C.F()""
+ IL_0006: stloc.s V_7
+ IL_0008: ldloc.s V_7
+ IL_000a: stloc.0
+ IL_000b: ldloc.0
+ IL_000c: brtrue.s IL_0010
+ IL_000e: br.s IL_0086
+ IL_0010: ldloc.0
+ IL_0011: isinst ""int?""
+ IL_0016: unbox.any ""int?""
+ IL_001b: stloc.s V_10
+ IL_001d: ldloca.s V_10
+ IL_001f: call ""int int?.GetValueOrDefault()""
+ IL_0024: stloc.1
+ IL_0025: ldloca.s V_10
+ IL_0027: call ""bool int?.HasValue.get""
+ IL_002c: brfalse.s IL_0036
+ IL_002e: ldloc.1
+ IL_002f: ldc.i4.1
+ IL_0030: beq.s IL_0034
+ IL_0032: br.s IL_0036
+ IL_0034: br.s IL_0088
+ IL_0036: ldloc.0
+ IL_0037: isinst ""byte?""
+ IL_003c: unbox.any ""byte?""
+ IL_0041: stloc.s V_11
+ IL_0043: ldloca.s V_11
+ IL_0045: call ""byte byte?.GetValueOrDefault()""
+ IL_004a: stloc.2
+ IL_004b: ldloca.s V_11
+ IL_004d: call ""bool byte?.HasValue.get""
+ IL_0052: brfalse.s IL_0060
+ IL_0054: br.s IL_0095
+ IL_0056: ldloc.2
+ IL_0057: stloc.2
+ IL_0058: ldloc.2
+ IL_0059: ldc.i4.1
+ IL_005a: beq.s IL_005e
+ IL_005c: br.s IL_0060
+ IL_005e: br.s IL_00bf
+ IL_0060: ldloc.0
+ IL_0061: isinst ""int?""
+ IL_0066: unbox.any ""int?""
+ IL_006b: stloc.s V_10
+ IL_006d: ldloca.s V_10
+ IL_006f: call ""int int?.GetValueOrDefault()""
+ IL_0074: stloc.1
+ IL_0075: ldloca.s V_10
+ IL_0077: call ""bool int?.HasValue.get""
+ IL_007c: brfalse.s IL_0082
+ IL_007e: br.s IL_00a9
+ IL_0080: br.s IL_00cc
+ IL_0082: ldloc.0
+ IL_0083: stloc.0
+ IL_0084: br.s IL_00db
+ IL_0086: br.s IL_00ea
+ IL_0088: ldstr ""int 1""
+ IL_008d: call ""void System.Console.WriteLine(string)""
+ IL_0092: nop
+ IL_0093: br.s IL_00ea
+ IL_0095: ldloc.2
+ IL_0096: stloc.3
+ IL_0097: call ""bool C.P()""
+ IL_009c: brtrue.s IL_00a0
+ IL_009e: br.s IL_0056
+ IL_00a0: ldloc.3
+ IL_00a1: call ""void System.Console.WriteLine(int)""
+ IL_00a6: nop
+ IL_00a7: br.s IL_00ea
+ IL_00a9: ldloc.1
+ IL_00aa: stloc.s V_4
+ IL_00ac: call ""bool C.P()""
+ IL_00b1: brtrue.s IL_00b5
+ IL_00b3: br.s IL_0080
+ IL_00b5: ldloc.s V_4
+ IL_00b7: call ""void System.Console.WriteLine(int)""
+ IL_00bc: nop
+ IL_00bd: br.s IL_00ea
+ IL_00bf: ldstr ""byte 1""
+ IL_00c4: call ""void System.Console.WriteLine(string)""
+ IL_00c9: nop
+ IL_00ca: br.s IL_00ea
+ IL_00cc: ldloc.1
+ IL_00cd: stloc.s V_5
+ IL_00cf: br.s IL_00d1
+ IL_00d1: ldloc.s V_5
+ IL_00d3: call ""void System.Console.WriteLine(int)""
+ IL_00d8: nop
+ IL_00d9: br.s IL_00ea
+ IL_00db: ldloc.0
+ IL_00dc: stloc.s V_6
+ IL_00de: br.s IL_00e0
+ IL_00e0: ldloc.s V_6
+ IL_00e2: call ""void System.Console.WriteLine(object)""
+ IL_00e7: nop
+ IL_00e8: br.s IL_00ea
+ IL_00ea: ret
+}
+");
+ }
+
[Fact]
public void If()
{
diff --git a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
index dad8fbff4d285..d0f4515e2a48e 100644
--- a/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
+++ b/src/Compilers/CSharp/Test/Emit/PDB/PDBTests.cs
@@ -2852,8 +2852,8 @@ class Student : Person { public double GPA; }
-
-
+
+
@@ -2943,8 +2943,8 @@ class Student : Person { public double GPA; }
-
-
+
+
@@ -6885,11 +6885,11 @@ .locals init (object V_0,
-
+
-
+
diff --git a/src/Compilers/Core/Portable/SynthesizedLocalKind.cs b/src/Compilers/Core/Portable/SynthesizedLocalKind.cs
index aba47777cff15..8b36f942c30bf 100644
--- a/src/Compilers/Core/Portable/SynthesizedLocalKind.cs
+++ b/src/Compilers/Core/Portable/SynthesizedLocalKind.cs
@@ -207,7 +207,7 @@ internal enum SynthesizedLocalKind
/// Temp created for pattern matching by type. This holds the value of an input value provisionally
/// converted to the type against which it is being matched.
///
- PatternMatching = 35,
+ SwitchCasePatternMatching = 35,
///
/// All values have to be less than or equal to